github.com/letsencrypt/boulder@v0.20251208.0/config/duration.go (about) 1 package config 2 3 import ( 4 "encoding/json" 5 "errors" 6 "reflect" 7 "time" 8 ) 9 10 // Duration is custom type embedding a time.Duration which allows defining 11 // methods such as serialization to YAML or JSON. 12 type Duration struct { 13 time.Duration `validate:"required"` 14 } 15 16 // DurationCustomTypeFunc enables registration of our custom config.Duration 17 // type as a time.Duration and performing validation on the configured value 18 // using the standard suite of validation functions. 19 func DurationCustomTypeFunc(field reflect.Value) any { 20 if c, ok := field.Interface().(Duration); ok { 21 return c.Duration 22 } 23 24 return reflect.Invalid 25 } 26 27 // ErrDurationMustBeString is returned when a non-string value is 28 // presented to be deserialized as a ConfigDuration 29 var ErrDurationMustBeString = errors.New("cannot JSON unmarshal something other than a string into a ConfigDuration") 30 31 // UnmarshalJSON parses a string into a ConfigDuration using 32 // time.ParseDuration. If the input does not unmarshal as a 33 // string, then UnmarshalJSON returns ErrDurationMustBeString. 34 func (d *Duration) UnmarshalJSON(b []byte) error { 35 s := "" 36 err := json.Unmarshal(b, &s) 37 if err != nil { 38 var jsonUnmarshalTypeErr *json.UnmarshalTypeError 39 if errors.As(err, &jsonUnmarshalTypeErr) { 40 return ErrDurationMustBeString 41 } 42 return err 43 } 44 dd, err := time.ParseDuration(s) 45 d.Duration = dd 46 return err 47 } 48 49 // MarshalJSON returns the string form of the duration, as a byte array. 50 func (d Duration) MarshalJSON() ([]byte, error) { 51 return []byte(d.Duration.String()), nil 52 } 53 54 // UnmarshalYAML uses the same format as JSON, but is called by the YAML 55 // parser (vs. the JSON parser). 56 func (d *Duration) UnmarshalYAML(unmarshal func(any) error) error { 57 var s string 58 err := unmarshal(&s) 59 if err != nil { 60 return err 61 } 62 dur, err := time.ParseDuration(s) 63 if err != nil { 64 return err 65 } 66 67 d.Duration = dur 68 return nil 69 } 70 71 // MarshalYAML returns the string form of the duration, as a string. 72 func (d Duration) MarshalYAML() (any, error) { 73 return d.Duration.String(), nil 74 }