support duration parse

This commit is contained in:
c9s 2020-12-08 15:55:47 +08:00
parent af0f45fe19
commit c66b140d90
2 changed files with 89 additions and 0 deletions

View File

@ -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

52
pkg/types/market_test.go Normal file
View File

@ -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)
})
}
}