util/time: add Marshal/Unmarshal to own Duration #184

Merged
vtolstov merged 2 commits from duration into v3 2023-02-13 14:05:17 +03:00
2 changed files with 61 additions and 0 deletions

View File

@ -1,6 +1,7 @@
package time
import (
"encoding/json"
"fmt"
"time"
)
@ -46,3 +47,36 @@ func ParseDuration(s string) (time.Duration, error) {
return td, err
}
func (d Duration) MarshalJSON() ([]byte, error) {
return json.Marshal(time.Duration(d).String())
}
func (d *Duration) UnmarshalJSON(b []byte) error {
var v interface{}
if err := json.Unmarshal(b, &v); err != nil {
return err
}
switch value := v.(type) {
case float64:
*d = Duration(time.Duration(value))
return nil
case string:
dv, err := time.ParseDuration(value)
if err != nil {
return err
}
*d = Duration(dv)
return nil
default:
return fmt.Errorf("invalid duration")
}
}
/*
func (d Duration) MarshalYAML() (interface{}, error) {
return nil, nil
}
func (d Duration) UnmarshalYAML(fn func(interface{}) error) error
*/

View File

@ -1,10 +1,37 @@
package time
import (
"bytes"
"encoding/json"
"testing"
"time"
)
func TestMarshalJSON(t *testing.T) {
d := Duration(10000000)
buf, err := json.Marshal(d)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(buf, []byte(`"10ms"`)) {
t.Fatalf("invalid duration: %s != %s", buf, `"10ms"`)
}
}
func TestUnmarshalJSON(t *testing.T) {
type str struct {
TTL Duration `json:"ttl"`
}
v := &str{}
err := json.Unmarshal([]byte(`{"ttl":"10ms"}`), v)
if err != nil {
t.Fatal(err)
} else if v.TTL != 10000000 {
t.Fatalf("invalid duration %v != 10000000", v.TTL)
}
}
func TestParseDuration(t *testing.T) {
var td time.Duration
var err error