diff --git a/pkg/types/market.go b/pkg/types/market.go index 7087ca459..9e57b9384 100644 --- a/pkg/types/market.go +++ b/pkg/types/market.go @@ -1,10 +1,47 @@ package types import ( + "encoding/json" + "fmt" "math" "strconv" + "time" ) +type Duration time.Duration + +func (d *Duration) UnmarshalJSON(data []byte) error { + var o interface{} + + if err := json.Unmarshal(data, &o); err != nil { + return err + } + + switch t := o.(type) { + case string: + dd, err := time.ParseDuration(t) + if err != nil { + return err + } + + *d = Duration(dd) + + case float64: + *d = Duration(int64(t * float64(time.Second))) + + case int64: + *d = Duration(t * int64(time.Second)) + case int: + *d = Duration(t * int(time.Second)) + + default: + return fmt.Errorf("unsupported type %T value: %v", t, t) + + } + + return nil +} + type Market struct { Symbol string PricePrecision int diff --git a/pkg/types/market_test.go b/pkg/types/market_test.go new file mode 100644 index 000000000..dd1225f2f --- /dev/null +++ b/pkg/types/market_test.go @@ -0,0 +1,52 @@ +package types + +import ( + "encoding/json" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestDurationParse(t *testing.T) { + type A struct { + Duration Duration `json:"duration"` + } + + type testcase struct { + name string + input string + expected Duration + } + + var tests = []testcase{ + { + name: "int to second", + input: `{ "duration": 1 }`, + expected: Duration(time.Second), + }, + { + name: "float64 to second", + input: `{ "duration": 1.1 }`, + expected: Duration(time.Second + 100 * time.Millisecond), + }, + { + name: "2m", + input: `{ "duration": "2m" }`, + expected: Duration(2 * time.Minute), + }, + { + name: "2m3s", + input: `{ "duration": "2m3s" }`, + expected: Duration(2 * time.Minute + 3 * time.Second), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + var a A + err := json.Unmarshal([]byte(test.input), &a) + assert.NoError(t, err) + assert.Equal(t, test.expected, a.Duration) + }) + } +}