committed by
Thomas Pelletier
parent
8fe62057ea
commit
e87c92d4f4
+17
-13
@@ -91,23 +91,25 @@ func isPrimitive(mtype reflect.Type) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the given marshal type maps to a Tree slice
|
// Check if the given marshal type maps to a Tree slice or array
|
||||||
func isTreeSlice(mtype reflect.Type) bool {
|
func isTreeSequence(mtype reflect.Type) bool {
|
||||||
switch mtype.Kind() {
|
switch mtype.Kind() {
|
||||||
case reflect.Slice:
|
case reflect.Ptr:
|
||||||
return !isOtherSlice(mtype)
|
return isTreeSequence(mtype.Elem())
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
return isTree(mtype.Elem())
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the given marshal type maps to a non-Tree slice
|
// Check if the given marshal type maps to a non-Tree slice or array
|
||||||
func isOtherSlice(mtype reflect.Type) bool {
|
func isOtherSequence(mtype reflect.Type) bool {
|
||||||
switch mtype.Kind() {
|
switch mtype.Kind() {
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
return isOtherSlice(mtype.Elem())
|
return isOtherSequence(mtype.Elem())
|
||||||
case reflect.Slice:
|
case reflect.Slice, reflect.Array:
|
||||||
return isPrimitive(mtype.Elem()) || isOtherSlice(mtype.Elem())
|
return !isTreeSequence(mtype)
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -116,6 +118,8 @@ func isOtherSlice(mtype reflect.Type) bool {
|
|||||||
// Check if the given marshal type maps to a Tree
|
// Check if the given marshal type maps to a Tree
|
||||||
func isTree(mtype reflect.Type) bool {
|
func isTree(mtype reflect.Type) bool {
|
||||||
switch mtype.Kind() {
|
switch mtype.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
return isTree(mtype.Elem())
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
return true
|
return true
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
@@ -406,9 +410,9 @@ func (e *Encoder) valueToToml(mtype reflect.Type, mval reflect.Value) (interface
|
|||||||
return callCustomMarshaler(mval)
|
return callCustomMarshaler(mval)
|
||||||
case isTree(mtype):
|
case isTree(mtype):
|
||||||
return e.valueToTree(mtype, mval)
|
return e.valueToTree(mtype, mval)
|
||||||
case isTreeSlice(mtype):
|
case isTreeSequence(mtype):
|
||||||
return e.valueToTreeSlice(mtype, mval)
|
return e.valueToTreeSlice(mtype, mval)
|
||||||
case isOtherSlice(mtype):
|
case isOtherSequence(mtype):
|
||||||
return e.valueToOtherSlice(mtype, mval)
|
return e.valueToOtherSlice(mtype, mval)
|
||||||
default:
|
default:
|
||||||
switch mtype.Kind() {
|
switch mtype.Kind() {
|
||||||
@@ -687,12 +691,12 @@ func (d *Decoder) valueFromToml(mtype reflect.Type, tval interface{}, mval1 *ref
|
|||||||
}
|
}
|
||||||
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a tree", tval, tval)
|
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a tree", tval, tval)
|
||||||
case []*Tree:
|
case []*Tree:
|
||||||
if isTreeSlice(mtype) {
|
if isTreeSequence(mtype) {
|
||||||
return d.valueFromTreeSlice(mtype, t)
|
return d.valueFromTreeSlice(mtype, t)
|
||||||
}
|
}
|
||||||
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to trees", tval, tval)
|
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to trees", tval, tval)
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
if isOtherSlice(mtype) {
|
if isOtherSequence(mtype) {
|
||||||
return d.valueFromOtherSlice(mtype, t)
|
return d.valueFromOtherSlice(mtype, t)
|
||||||
}
|
}
|
||||||
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a slice", tval, tval)
|
return reflect.ValueOf(nil), fmt.Errorf("Can't convert %v(%T) to a slice", tval, tval)
|
||||||
|
|||||||
+82
-3
@@ -433,12 +433,36 @@ type tomlTypeCheckTest struct {
|
|||||||
|
|
||||||
func TestTypeChecks(t *testing.T) {
|
func TestTypeChecks(t *testing.T) {
|
||||||
tests := []tomlTypeCheckTest{
|
tests := []tomlTypeCheckTest{
|
||||||
{"integer", 2, 0},
|
{"bool", true, 0},
|
||||||
|
{"bool", false, 0},
|
||||||
|
{"int", int(2), 0},
|
||||||
|
{"int8", int8(2), 0},
|
||||||
|
{"int16", int16(2), 0},
|
||||||
|
{"int32", int32(2), 0},
|
||||||
|
{"int64", int64(2), 0},
|
||||||
|
{"uint", uint(2), 0},
|
||||||
|
{"uint8", uint8(2), 0},
|
||||||
|
{"uint16", uint16(2), 0},
|
||||||
|
{"uint32", uint32(2), 0},
|
||||||
|
{"uint64", uint64(2), 0},
|
||||||
|
{"float32", float32(3.14), 0},
|
||||||
|
{"float64", float64(3.14), 0},
|
||||||
|
{"string", "lorem ipsum", 0},
|
||||||
{"time", time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC), 0},
|
{"time", time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC), 0},
|
||||||
{"stringlist", []string{"hello", "hi"}, 1},
|
{"stringlist", []string{"hello", "hi"}, 1},
|
||||||
|
{"stringlistptr", &[]string{"hello", "hi"}, 1},
|
||||||
|
{"stringarray", [2]string{"hello", "hi"}, 1},
|
||||||
|
{"stringarrayptr", &[2]string{"hello", "hi"}, 1},
|
||||||
{"timelist", []time.Time{time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 1},
|
{"timelist", []time.Time{time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 1},
|
||||||
|
{"timelistptr", &[]time.Time{time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 1},
|
||||||
|
{"timearray", [1]time.Time{time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 1},
|
||||||
|
{"timearrayptr", &[1]time.Time{time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, 1},
|
||||||
{"objectlist", []tomlTypeCheckTest{}, 2},
|
{"objectlist", []tomlTypeCheckTest{}, 2},
|
||||||
|
{"objectlistptr", &[]tomlTypeCheckTest{}, 2},
|
||||||
|
{"objectarray", [2]tomlTypeCheckTest{{}, {}}, 2},
|
||||||
|
{"objectlistptr", &[2]tomlTypeCheckTest{{}, {}}, 2},
|
||||||
{"object", tomlTypeCheckTest{}, 3},
|
{"object", tomlTypeCheckTest{}, 3},
|
||||||
|
{"objectptr", &tomlTypeCheckTest{}, 3},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
@@ -446,8 +470,8 @@ func TestTypeChecks(t *testing.T) {
|
|||||||
expected[test.typ] = true
|
expected[test.typ] = true
|
||||||
result := []bool{
|
result := []bool{
|
||||||
isPrimitive(reflect.TypeOf(test.item)),
|
isPrimitive(reflect.TypeOf(test.item)),
|
||||||
isOtherSlice(reflect.TypeOf(test.item)),
|
isOtherSequence(reflect.TypeOf(test.item)),
|
||||||
isTreeSlice(reflect.TypeOf(test.item)),
|
isTreeSequence(reflect.TypeOf(test.item)),
|
||||||
isTree(reflect.TypeOf(test.item)),
|
isTree(reflect.TypeOf(test.item)),
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(expected, result) {
|
if !reflect.DeepEqual(expected, result) {
|
||||||
@@ -1699,3 +1723,58 @@ func TestTreeMarshal(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMarshalArrays(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Data interface{}
|
||||||
|
Expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Data: struct {
|
||||||
|
XY [2]int
|
||||||
|
}{
|
||||||
|
XY: [2]int{1, 2},
|
||||||
|
},
|
||||||
|
Expected: `XY = [1,2]
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: struct {
|
||||||
|
XY [1][2]int
|
||||||
|
}{
|
||||||
|
XY: [1][2]int{{1, 2}},
|
||||||
|
},
|
||||||
|
Expected: `XY = [[1,2]]
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: struct {
|
||||||
|
XY [1][]int
|
||||||
|
}{
|
||||||
|
XY: [1][]int{{1, 2}},
|
||||||
|
},
|
||||||
|
Expected: `XY = [[1,2]]
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Data: struct {
|
||||||
|
XY [][2]int
|
||||||
|
}{
|
||||||
|
XY: [][2]int{{1, 2}},
|
||||||
|
},
|
||||||
|
Expected: `XY = [[1,2]]
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range cases {
|
||||||
|
t.Run("", func(t *testing.T) {
|
||||||
|
result, err := Marshal(tc.Data)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(result, []byte(tc.Expected)) {
|
||||||
|
t.Errorf("Bad marshal: expected\n-----\n%s\n-----\ngot\n-----\n%s\n-----\n", []byte(tc.Expected), result)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user