Skip to content

Commit fbde15a

Browse files
authored
feat: Add Duration configtype (#1014)
This adds a wrapper to `time.Duration` that can be used in plugin configs that require some sort of time duration. We wrap `time.Duration` so that we can control the spec and possibly extend it in the future.
1 parent 05e1edd commit fbde15a

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

configtype/duration.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package configtype
2+
3+
import (
4+
"encoding/json"
5+
"time"
6+
)
7+
8+
// Duration is a wrapper around time.Duration that should be used in config
9+
// when a duration type is required. We wrap the time.Duration type so that
10+
// the spec can be extended in the future to support other types of durations
11+
// (e.g. a duration that is specified in days).
12+
type Duration struct {
13+
duration time.Duration
14+
}
15+
16+
func NewDuration(d time.Duration) Duration {
17+
return Duration{
18+
duration: d,
19+
}
20+
}
21+
22+
func (d *Duration) UnmarshalJSON(b []byte) error {
23+
var s string
24+
if err := json.Unmarshal(b, &s); err != nil {
25+
return err
26+
}
27+
duration, err := time.ParseDuration(s)
28+
if err != nil {
29+
return err
30+
}
31+
*d = Duration{duration: duration}
32+
return nil
33+
}
34+
35+
func (d *Duration) MarshalJSON() ([]byte, error) {
36+
return json.Marshal(d.duration.String())
37+
}
38+
39+
func (d *Duration) Duration() time.Duration {
40+
return d.duration
41+
}

configtype/duration_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package configtype
2+
3+
import (
4+
"encoding/json"
5+
"testing"
6+
"time"
7+
)
8+
9+
func TestDuration(t *testing.T) {
10+
cases := []struct {
11+
give string
12+
want time.Duration
13+
}{
14+
{"1ns", 1 * time.Nanosecond},
15+
{"20s", 20 * time.Second},
16+
{"-50m30s", -50*time.Minute - 30*time.Second},
17+
}
18+
for _, tc := range cases {
19+
var d Duration
20+
err := json.Unmarshal([]byte(`"`+tc.give+`"`), &d)
21+
if err != nil {
22+
t.Fatalf("error calling Unmarshal(%q): %v", tc.give, err)
23+
}
24+
if d.Duration() != tc.want {
25+
t.Errorf("Unmarshal(%q) = %v, want %v", tc.give, d.Duration(), tc.want)
26+
}
27+
}
28+
}

0 commit comments

Comments
 (0)