Support time.duration (#248)
This commit is contained in:
committed by
Thomas Pelletier
parent
81a861c69d
commit
aa79e12a97
+10
@@ -352,6 +352,9 @@ func (e *Encoder) valueToToml(mtype reflect.Type, mval reflect.Value) (interface
|
|||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
return mval.Bool(), nil
|
return mval.Bool(), nil
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
if mtype.Kind() == reflect.Int64 && mtype == reflect.TypeOf(time.Duration(1)) {
|
||||||
|
return fmt.Sprint(mval), nil
|
||||||
|
}
|
||||||
return mval.Int(), nil
|
return mval.Int(), nil
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
return mval.Uint(), nil
|
return mval.Uint(), nil
|
||||||
@@ -566,6 +569,13 @@ func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}) (reflect.V
|
|||||||
return val.Convert(mtype), nil
|
return val.Convert(mtype), nil
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
val := reflect.ValueOf(tval)
|
val := reflect.ValueOf(tval)
|
||||||
|
if mtype.Kind() == reflect.Int64 && mtype == reflect.TypeOf(time.Duration(1)) && val.Kind() == reflect.String {
|
||||||
|
d, err := time.ParseDuration(val.String())
|
||||||
|
if err != nil {
|
||||||
|
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v. %s", tval, tval, mtype.String(), err)
|
||||||
|
}
|
||||||
|
return reflect.ValueOf(d), nil
|
||||||
|
}
|
||||||
if !val.Type().ConvertibleTo(mtype) {
|
if !val.Type().ConvertibleTo(mtype) {
|
||||||
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
|
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v", tval, tval, mtype.String())
|
||||||
}
|
}
|
||||||
|
|||||||
+118
@@ -1002,3 +1002,121 @@ func TestMarshalMap(t *testing.T) {
|
|||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type testDuration struct {
|
||||||
|
Nanosec time.Duration `toml:"nanosec"`
|
||||||
|
Microsec1 time.Duration `toml:"microsec1"`
|
||||||
|
Microsec2 *time.Duration `toml:"microsec2"`
|
||||||
|
Millisec time.Duration `toml:"millisec"`
|
||||||
|
Sec time.Duration `toml:"sec"`
|
||||||
|
Min time.Duration `toml:"min"`
|
||||||
|
Hour time.Duration `toml:"hour"`
|
||||||
|
Mixed time.Duration `toml:"mixed"`
|
||||||
|
AString string `toml:"a_string"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var testDurationToml = []byte(`
|
||||||
|
nanosec = "1ns"
|
||||||
|
microsec1 = "1us"
|
||||||
|
microsec2 = "1µs"
|
||||||
|
millisec = "1ms"
|
||||||
|
sec = "1s"
|
||||||
|
min = "1m"
|
||||||
|
hour = "1h"
|
||||||
|
mixed = "1h1m1s1ms1µs1ns"
|
||||||
|
a_string = "15s"
|
||||||
|
`)
|
||||||
|
|
||||||
|
func TestUnmarshalDuration(t *testing.T) {
|
||||||
|
buf := bytes.NewBuffer(testDurationToml)
|
||||||
|
|
||||||
|
result := testDuration{}
|
||||||
|
err := NewDecoder(buf).Decode(&result)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
ms := time.Duration(1) * time.Microsecond
|
||||||
|
expected := testDuration{
|
||||||
|
Nanosec: 1,
|
||||||
|
Microsec1: time.Microsecond,
|
||||||
|
Microsec2: &ms,
|
||||||
|
Millisec: time.Millisecond,
|
||||||
|
Sec: time.Second,
|
||||||
|
Min: time.Minute,
|
||||||
|
Hour: time.Hour,
|
||||||
|
Mixed: time.Hour +
|
||||||
|
time.Minute +
|
||||||
|
time.Second +
|
||||||
|
time.Millisecond +
|
||||||
|
time.Microsecond +
|
||||||
|
time.Nanosecond,
|
||||||
|
AString: "15s",
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(result, expected) {
|
||||||
|
resStr, _ := json.MarshalIndent(result, "", " ")
|
||||||
|
expStr, _ := json.MarshalIndent(expected, "", " ")
|
||||||
|
t.Errorf("Bad unmarshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expStr, resStr)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testDurationToml2 = []byte(`a_string = "15s"
|
||||||
|
hour = "1h0m0s"
|
||||||
|
microsec1 = "1µs"
|
||||||
|
microsec2 = "1µs"
|
||||||
|
millisec = "1ms"
|
||||||
|
min = "1m0s"
|
||||||
|
mixed = "1h1m1.001001001s"
|
||||||
|
nanosec = "1ns"
|
||||||
|
sec = "1s"
|
||||||
|
`)
|
||||||
|
|
||||||
|
func TestMarshalDuration(t *testing.T) {
|
||||||
|
ms := time.Duration(1) * time.Microsecond
|
||||||
|
data := testDuration{
|
||||||
|
Nanosec: 1,
|
||||||
|
Microsec1: time.Microsecond,
|
||||||
|
Microsec2: &ms,
|
||||||
|
Millisec: time.Millisecond,
|
||||||
|
Sec: time.Second,
|
||||||
|
Min: time.Minute,
|
||||||
|
Hour: time.Hour,
|
||||||
|
Mixed: time.Hour +
|
||||||
|
time.Minute +
|
||||||
|
time.Second +
|
||||||
|
time.Millisecond +
|
||||||
|
time.Microsecond +
|
||||||
|
time.Nanosecond,
|
||||||
|
AString: "15s",
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err := NewEncoder(&buf).Encode(data)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
expected := testDurationToml2
|
||||||
|
result := buf.Bytes()
|
||||||
|
if !bytes.Equal(result, expected) {
|
||||||
|
t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", expected, result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type testBadDuration struct {
|
||||||
|
Val time.Duration `toml:"val"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var testBadDurationToml = []byte(`val = "1z"`)
|
||||||
|
|
||||||
|
func TestUnmarshalBadDuration(t *testing.T) {
|
||||||
|
buf := bytes.NewBuffer(testBadDurationToml)
|
||||||
|
|
||||||
|
result := testBadDuration{}
|
||||||
|
err := NewDecoder(buf).Decode(&result)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal()
|
||||||
|
}
|
||||||
|
if err.Error() != "(1, 1): Can't convert 1z(string) to time.Duration. time: unknown unit z in duration 1z" {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user