package home import ( "time" "github.com/AdguardTeam/golibs/errors" ) // Duration is a wrapper for time.Duration providing functionality for encoding. type Duration struct { // time.Duration is embedded here to avoid implementing all the methods. time.Duration } // String implements the fmt.Stringer interface for Duration. It wraps // time.Duration.String method and additionally cuts off non-leading zero values // of minutes and seconds. Some values which are differ between the // implementations: // // Duration: "1m", time.Duration: "1m0s" // Duration: "1h", time.Duration: "1h0m0s" // Duration: "1h1m", time.Duration: "1h1m0s" // func (d Duration) String() (str string) { str = d.Duration.String() secs := d.Seconds() var secsInt int if secsInt = int(secs); float64(secsInt) != secs || secsInt%60 != 0 { return str } const ( tailMin = len(`0s`) tailMinSec = len(`0m0s`) ) if (secsInt%3600)/60 != 0 { return str[:len(str)-tailMin] } return str[:len(str)-tailMinSec] } // MarshalText implements the encoding.TextMarshaler interface for Duration. func (d Duration) MarshalText() (text []byte, err error) { return []byte(d.String()), nil } // UnmarshalText implements the encoding.TextUnmarshaler interface for // *Duration. // // TODO(e.burkov): Make it able to parse larger units like days. func (d *Duration) UnmarshalText(b []byte) (err error) { defer func() { err = errors.Annotate(err, "unmarshalling duration: %w") }() d.Duration, err = time.ParseDuration(string(b)) return err }