Files
skybridge/internal/domain/duration.go
2025-08-23 17:57:39 -04:00

58 lines
1.4 KiB
Go

package domain
import (
"encoding/json"
"fmt"
"time"
)
// Duration is a wrapper around time.Duration that can unmarshal from both
// string duration formats (like "168h") and nanosecond integers
type Duration struct {
time.Duration
}
// UnmarshalJSON implements json.Unmarshaler interface
func (d *Duration) UnmarshalJSON(data []byte) error {
// Try to unmarshal as string first (e.g., "168h", "24h", "30m")
var str string
if err := json.Unmarshal(data, &str); err == nil {
duration, err := time.ParseDuration(str)
if err != nil {
return fmt.Errorf("invalid duration format: %s", str)
}
d.Duration = duration
return nil
}
// Try to unmarshal as integer (nanoseconds)
var ns int64
if err := json.Unmarshal(data, &ns); err == nil {
d.Duration = time.Duration(ns)
return nil
}
return fmt.Errorf("duration must be either a string (e.g., '168h') or integer nanoseconds")
}
// MarshalJSON implements json.Marshaler interface
func (d Duration) MarshalJSON() ([]byte, error) {
// Always marshal as nanoseconds for consistency
return json.Marshal(int64(d.Duration))
}
// String returns the string representation of the duration
func (d Duration) String() string {
return d.Duration.String()
}
// Int64 returns the duration in nanoseconds for validator compatibility
func (d Duration) Int64() int64 {
return int64(d.Duration)
}
// IsZero returns true if the duration is zero
func (d Duration) IsZero() bool {
return d.Duration == 0
}