From 82ef273b8eaccefa80f9c61ef7461cbf7caca8c7 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 14 Apr 2020 19:55:26 -0700 Subject: [PATCH] feat: add and use a duration helper type --- autonat.go | 4 +++- types.go | 20 ++++++++++++++++++++ types_test.go | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/autonat.go b/autonat.go index 05009ff..a1a3f69 100644 --- a/autonat.go +++ b/autonat.go @@ -75,5 +75,7 @@ type AutoNATThrottleConfig struct { // Interval specifies how frequently this node should reset the // global/peer dialback limits. - Interval string + // + // When unset, this defaults to 1 minute. + Interval Duration `json:",omitempty"` } diff --git a/types.go b/types.go index 58451c6..90363e3 100644 --- a/types.go +++ b/types.go @@ -2,6 +2,7 @@ package config import ( "encoding/json" + "time" ) // Strings is a helper type that (un)marshals a single string to/from a single @@ -39,3 +40,22 @@ func (o Strings) MarshalJSON() ([]byte, error) { var _ json.Unmarshaler = (*Strings)(nil) var _ json.Marshaler = (*Strings)(nil) + +// Duration wraps time.Duration to provide json serialization and deserialization. +// +// NOTE: the zero value encodes to an empty string. +type Duration time.Duration + +func (d *Duration) UnmarshalText(text []byte) error { + dur, err := time.ParseDuration(string(text)) + *d = Duration(dur) + return err +} + +func (d Duration) MarshalText() ([]byte, error) { + return []byte(time.Duration(d).String()), nil +} + +func (d Duration) String() string { + return time.Duration(d).String() +} diff --git a/types_test.go b/types_test.go index 7523962..295ce92 100644 --- a/types_test.go +++ b/types_test.go @@ -3,8 +3,40 @@ package config import ( "encoding/json" "testing" + "time" ) +func TestDuration(t *testing.T) { + out, err := json.Marshal(Duration(time.Second)) + if err != nil { + t.Fatal(err) + + } + expected := "\"1s\"" + if string(out) != expected { + t.Fatalf("expected %s, got %s", expected, string(out)) + } + var d Duration + err = json.Unmarshal(out, &d) + if err != nil { + t.Fatal(err) + } + if time.Duration(d) != time.Second { + t.Fatal("expected a second") + } + type Foo struct { + D Duration `json:",omitempty"` + } + out, err = json.Marshal(new(Foo)) + if err != nil { + t.Fatal(err) + } + expected = "{}" + if string(out) != expected { + t.Fatal("expected omitempty to omit the duration") + } +} + func TestOneStrings(t *testing.T) { out, err := json.Marshal(Strings{"one"}) if err != nil {