Files
go-tyme/dur/duration.go

80 lines
1.9 KiB
Go

package dur
import (
"encoding/json"
"strconv"
"time"
"gopkg.in/yaml.v3"
)
// Duration is a wrapper around time.Duration that implements JSON and YAML
// marshaler and unmarshaler interfaces.
//
// When unmarshaling, string values in JSON and YAML are parsed using
// time.ParseDuration. Numeric values are parsed as number of seconds.
//
// When marshaling, the duration is formatted as a string using time.Duration's
// String method.
type Duration time.Duration
// MarshalJSON implements the json.Marshaler interface, returning the duration
// as a string in the format "1h2m3s", same as time.Duration.String().
func (d Duration) MarshalJSON() ([]byte, error) {
return json.Marshal(time.Duration(d).String())
}
// UmarshalJSON implements the json.Unmarshaler interface. Supports string,
// numeric JSON types, converting them to a Duration using ParseDuration.
func (d *Duration) UnmarshalJSON(b []byte) error {
var x interface{}
if err := json.Unmarshal(b, &x); err != nil {
return err
}
pd, err := Parse(x)
if err != nil {
return err
}
*d = pd
return nil
}
// MarshalJSON implements the yaml.Marshaler interface, returning the duration
// as a string in the format 1h2m3s, same as time.Duration.String().
func (d Duration) MarshalYAML() (interface{}, error) {
return time.Duration(d).String(), nil
}
// UmarshalYAML implements the yaml.Unmarshaler interface. Supports string, int
// and float YAML types, converting them to a Duration using ParseDuration.
func (d *Duration) UnmarshalYAML(node *yaml.Node) error {
var x interface{}
var err error
switch node.Tag {
case "!!str":
x = node.Value
case "!!int":
x, err = strconv.Atoi(node.Value)
case "!!float":
x, err = strconv.ParseFloat(node.Value, 64)
default:
return &yaml.TypeError{Errors: []string{"invalid duration"}}
}
if err != nil {
return err
}
pd, err := Parse(x)
if err != nil {
return err
}
*d = pd
return nil
}