70 lines
1.9 KiB
Go
70 lines
1.9 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"reflect"
|
|
"time"
|
|
)
|
|
|
|
// Duration is custom type embedding a time.Duration which allows defining
|
|
// methods such as serialization to YAML or JSON.
|
|
type Duration struct {
|
|
time.Duration `validate:"required"`
|
|
}
|
|
|
|
// DurationCustomTypeFunc enables registration of our custom config.Duration
|
|
// type as a time.Duration and performing validation on the configured value
|
|
// using the standard suite of validation functions.
|
|
func DurationCustomTypeFunc(field reflect.Value) interface{} {
|
|
if c, ok := field.Interface().(Duration); ok {
|
|
return c.Duration
|
|
}
|
|
|
|
return reflect.Invalid
|
|
}
|
|
|
|
// ErrDurationMustBeString is returned when a non-string value is
|
|
// presented to be deserialized as a ConfigDuration
|
|
var ErrDurationMustBeString = errors.New("cannot JSON unmarshal something other than a string into a ConfigDuration")
|
|
|
|
// UnmarshalJSON parses a string into a ConfigDuration using
|
|
// time.ParseDuration. If the input does not unmarshal as a
|
|
// string, then UnmarshalJSON returns ErrDurationMustBeString.
|
|
func (d *Duration) UnmarshalJSON(b []byte) error {
|
|
s := ""
|
|
err := json.Unmarshal(b, &s)
|
|
if err != nil {
|
|
var jsonUnmarshalTypeErr *json.UnmarshalTypeError
|
|
if errors.As(err, &jsonUnmarshalTypeErr) {
|
|
return ErrDurationMustBeString
|
|
}
|
|
return err
|
|
}
|
|
dd, err := time.ParseDuration(s)
|
|
d.Duration = dd
|
|
return err
|
|
}
|
|
|
|
// MarshalJSON returns the string form of the duration, as a byte array.
|
|
func (d Duration) MarshalJSON() ([]byte, error) {
|
|
return []byte(d.Duration.String()), nil
|
|
}
|
|
|
|
// UnmarshalYAML uses the same format as JSON, but is called by the YAML
|
|
// parser (vs. the JSON parser).
|
|
func (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|
var s string
|
|
err := unmarshal(&s)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
dur, err := time.ParseDuration(s)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
d.Duration = dur
|
|
return nil
|
|
}
|