From 323fe5d06373db38a4aa9d0c57885c4d68856744 Mon Sep 17 00:00:00 2001 From: jixiuf Date: Wed, 22 Apr 2020 10:48:12 +0800 Subject: [PATCH] fix #356 Unmarshal support []string ,[]int ... (#361) * fix #356 Unmarshal support []string ,[]int ... * try make codecov happy. --- marshal.go | 21 +++++++++++++++ marshal_test.go | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/marshal.go b/marshal.go index e921a80..db05c58 100644 --- a/marshal.go +++ b/marshal.go @@ -714,6 +714,22 @@ func (d *Decoder) valueFromOtherSlice(mtype reflect.Type, tval []interface{}) (r return mval, nil } +// Convert toml value to marshal primitive slice, using marshal type +func (d *Decoder) valueFromOtherSliceI(mtype reflect.Type, tval interface{}) (reflect.Value, error) { + val := reflect.ValueOf(tval) + + lenght := val.Len() + mval := reflect.MakeSlice(mtype, lenght, lenght) + for i := 0; i < lenght; i++ { + val, err := d.valueFromToml(mtype.Elem(), val.Index(i).Interface(), nil) + if err != nil { + return mval, err + } + mval.Index(i).Set(val) + } + return mval, nil +} + // Convert toml value to marshal value, using marshal type. When mval1 is non-nil // and the given type is a struct value, merge fields into it. func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}, mval1 *reflect.Value) (reflect.Value, error) { @@ -857,6 +873,11 @@ func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}, mval1 *ref ival := mval1.Elem() return d.valueFromToml(mval1.Elem().Type(), t, &ival) } + case reflect.Slice: + if isOtherSequence(mtype) && isOtherSequence(reflect.TypeOf(t)) { + return d.valueFromOtherSliceI(mtype, t) + } + return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v(%v)", tval, tval, mtype, mtype.Kind()) default: return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to %v(%v)", tval, tval, mtype, mtype.Kind()) } diff --git a/marshal_test.go b/marshal_test.go index 7f4fdc6..5d66652 100644 --- a/marshal_test.go +++ b/marshal_test.go @@ -2813,3 +2813,72 @@ func TestUnmarshalNil(t *testing.T) { t.Errorf("Expected err from nil marshal") } } + +var sliceTomlDemo = []byte(`str_slice = ["Howdy","Hey There"] +str_slice_ptr= ["Howdy","Hey There"] +int_slice=[1,2] +int_slice_ptr=[1,2] +[[struct_slice]] +String2="1" +[[struct_slice]] +String2="2" +[[struct_slice_ptr]] +String2="1" +[[struct_slice_ptr]] +String2="2" +`) + +type sliceStruct struct { + Slice []string ` toml:"str_slice" ` + SlicePtr *[]string ` toml:"str_slice_ptr" ` + IntSlice []int ` toml:"int_slice" ` + IntSlicePtr *[]int ` toml:"int_slice_ptr" ` + StructSlice []basicMarshalTestSubStruct ` toml:"struct_slice" ` + StructSlicePtr *[]basicMarshalTestSubStruct ` toml:"struct_slice_ptr" ` +} + +func TestUnmarshalSlice(t *testing.T) { + tree, _ := LoadBytes(sliceTomlDemo) + tree, _ = TreeFromMap(tree.ToMap()) + + var actual sliceStruct + err := tree.Unmarshal(&actual) + if err != nil { + t.Error("shound not err", err) + } + expected := sliceStruct{ + Slice: []string{"Howdy", "Hey There"}, + SlicePtr: &[]string{"Howdy", "Hey There"}, + IntSlice: []int{1, 2}, + IntSlicePtr: &[]int{1, 2}, + StructSlice: []basicMarshalTestSubStruct{{"1"}, {"2"}}, + StructSlicePtr: &[]basicMarshalTestSubStruct{{"1"}, {"2"}}, + } + if !reflect.DeepEqual(actual, expected) { + t.Errorf("Bad unmarshal: expected %v, got %v", expected, actual) + } + +} + +func TestUnmarshalSliceFail(t *testing.T) { + tree, _ := TreeFromMap(map[string]interface{}{ + "str_slice": []int{1, 2}, + }) + + var actual sliceStruct + err := tree.Unmarshal(&actual) + if err.Error() != "(0, 0): Can't convert 1(int64) to string" { + t.Error("expect err:(0, 0): Can't convert 1(int64) to string but got ", err) + } +} + +func TestUnmarshalSliceFail2(t *testing.T) { + tree, _ := Load(`str_slice=[1,2]`) + + var actual sliceStruct + err := tree.Unmarshal(&actual) + if err.Error() != "(1, 1): Can't convert 1(int64) to string" { + t.Error("expect err:(1, 1): Can't convert 1(int64) to string but got ", err) + } + +}