Skip to content

Commit

Permalink
Merge pull request #280 from 56quarters/duration-json
Browse files Browse the repository at this point in the history
Add methods to model.Duration for JSON marshalling and unmarshalling
  • Loading branch information
roidelapluie authored Mar 9, 2021
2 parents 47ee79a + 745afa4 commit 3ebd397
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 0 deletions.
20 changes: 20 additions & 0 deletions model/time.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package model

import (
"encoding/json"
"fmt"
"math"
"regexp"
Expand Down Expand Up @@ -254,6 +255,25 @@ func (d Duration) String() string {
return r
}

// MarshalJSON implements the json.Marshaler interface.
func (d Duration) MarshalJSON() ([]byte, error) {
return json.Marshal(d.String())
}

// UnmarshalJSON implements the json.Unmarshaler interface.
func (d *Duration) UnmarshalJSON(bytes []byte) error {
var s string
if err := json.Unmarshal(bytes, &s); err != nil {
return err
}
dur, err := ParseDuration(s)
if err != nil {
return err
}
*d = dur
return nil
}

// MarshalText implements the encoding.TextMarshaler interface.
func (d *Duration) MarshalText() ([]byte, error) {
return []byte(d.String()), nil
Expand Down
77 changes: 77 additions & 0 deletions model/time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package model

import (
"encoding/json"
"strconv"
"testing"
"time"
Expand Down Expand Up @@ -230,6 +231,82 @@ func TestDuration_UnmarshalText(t *testing.T) {
}
}

func TestDuration_UnmarshalJSON(t *testing.T) {
var cases = []struct {
in string
out time.Duration

expectedString string
}{
{
in: `"0"`,
out: 0,
expectedString: `"0s"`,
}, {
in: `"0w"`,
out: 0,
expectedString: `"0s"`,
}, {
in: `"0s"`,
out: 0,
}, {
in: `"324ms"`,
out: 324 * time.Millisecond,
}, {
in: `"3s"`,
out: 3 * time.Second,
}, {
in: `"5m"`,
out: 5 * time.Minute,
}, {
in: `"1h"`,
out: time.Hour,
}, {
in: `"4d"`,
out: 4 * 24 * time.Hour,
}, {
in: `"4d1h"`,
out: 4*24*time.Hour + time.Hour,
}, {
in: `"14d"`,
out: 14 * 24 * time.Hour,
expectedString: `"2w"`,
}, {
in: `"3w"`,
out: 3 * 7 * 24 * time.Hour,
}, {
in: `"3w2d1h"`,
out: 3*7*24*time.Hour + 2*24*time.Hour + time.Hour,
expectedString: `"23d1h"`,
}, {
in: `"10y"`,
out: 10 * 365 * 24 * time.Hour,
},
}

for _, c := range cases {
var d Duration
err := json.Unmarshal([]byte(c.in), &d)
if err != nil {
t.Errorf("Unexpected error on input %q", c.in)
}
if time.Duration(d) != c.out {
t.Errorf("Expected %v but got %v", c.out, d)
}
expectedString := c.expectedString
if c.expectedString == "" {
expectedString = c.in
}
bytes, err := json.Marshal(d)
if err != nil {
t.Errorf("Unexpected error on marshal of %v: %s", d, err)
}
if string(bytes) != expectedString {
t.Errorf("Expected duration string %q but got %q", c.in, d.String())
}
}
}

func TestParseBadDuration(t *testing.T) {
var cases = []string{
"1",
Expand Down

0 comments on commit 3ebd397

Please sign in to comment.