Fix unmarshaler error when a custom marshaler function is defined (#383)
Fixes #382
This commit is contained in:
+27
-3
@@ -93,7 +93,7 @@ func isPrimitive(mtype reflect.Type) bool {
|
|||||||
case reflect.String:
|
case reflect.String:
|
||||||
return true
|
return true
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
return isTimeType(mtype) || isCustomMarshaler(mtype) || isTextMarshaler(mtype)
|
return isTimeType(mtype)
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -115,6 +115,30 @@ func isTreeSequence(mtype reflect.Type) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the given marshal type maps to a slice or array of a custom marshaler type
|
||||||
|
func isCustomMarshalerSequence(mtype reflect.Type) bool {
|
||||||
|
switch mtype.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
return isCustomMarshalerSequence(mtype.Elem())
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
return isCustomMarshaler(mtype.Elem()) || isCustomMarshaler(reflect.New(mtype.Elem()).Type())
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the given marshal type maps to a slice or array of a text marshaler type
|
||||||
|
func isTextMarshalerSequence(mtype reflect.Type) bool {
|
||||||
|
switch mtype.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
return isTextMarshalerSequence(mtype.Elem())
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
return isTextMarshaler(mtype.Elem()) || isTextMarshaler(reflect.New(mtype.Elem()).Type())
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the given marshal type maps to a non-Tree slice or array
|
// Check if the given marshal type maps to a non-Tree slice or array
|
||||||
func isOtherSequence(mtype reflect.Type) bool {
|
func isOtherSequence(mtype reflect.Type) bool {
|
||||||
switch mtype.Kind() {
|
switch mtype.Kind() {
|
||||||
@@ -516,10 +540,10 @@ func (e *Encoder) valueToToml(mtype reflect.Type, mval reflect.Value) (interface
|
|||||||
return callTextMarshaler(mval)
|
return callTextMarshaler(mval)
|
||||||
case isTree(mtype):
|
case isTree(mtype):
|
||||||
return e.valueToTree(mtype, mval)
|
return e.valueToTree(mtype, mval)
|
||||||
|
case isOtherSequence(mtype), isCustomMarshalerSequence(mtype), isTextMarshalerSequence(mtype):
|
||||||
|
return e.valueToOtherSlice(mtype, mval)
|
||||||
case isTreeSequence(mtype):
|
case isTreeSequence(mtype):
|
||||||
return e.valueToTreeSlice(mtype, mval)
|
return e.valueToTreeSlice(mtype, mval)
|
||||||
case isOtherSequence(mtype):
|
|
||||||
return e.valueToOtherSlice(mtype, mval)
|
|
||||||
default:
|
default:
|
||||||
switch mtype.Kind() {
|
switch mtype.Kind() {
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
|
|||||||
+48
-1
@@ -911,6 +911,9 @@ var nestedCustomMarshalerData = customMarshalerParent{
|
|||||||
var nestedCustomMarshalerToml = []byte(`friends = ["Sally Fields"]
|
var nestedCustomMarshalerToml = []byte(`friends = ["Sally Fields"]
|
||||||
me = "Maiku Suteda"
|
me = "Maiku Suteda"
|
||||||
`)
|
`)
|
||||||
|
var nestedCustomMarshalerTomlForUnmarshal = []byte(`[friends]
|
||||||
|
FirstName = "Sally"
|
||||||
|
LastName = "Fields"`)
|
||||||
|
|
||||||
func TestCustomMarshaler(t *testing.T) {
|
func TestCustomMarshaler(t *testing.T) {
|
||||||
result, err := Marshal(customMarshalerData)
|
result, err := Marshal(customMarshalerData)
|
||||||
@@ -946,6 +949,26 @@ func TestTextMarshaler(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalTextMarshaler(t *testing.T) {
|
||||||
|
var nested = struct {
|
||||||
|
Friends textMarshaler `toml:"friends"`
|
||||||
|
}{}
|
||||||
|
|
||||||
|
var expected = struct {
|
||||||
|
Friends textMarshaler `toml:"friends"`
|
||||||
|
}{
|
||||||
|
Friends: textMarshaler{FirstName: "Sally", LastName: "Fields"},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := Unmarshal(nestedCustomMarshalerTomlForUnmarshal, &nested)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(nested, expected) {
|
||||||
|
t.Errorf("Bad unmarshal: expected %v, got %v", expected, nested)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestNestedTextMarshaler(t *testing.T) {
|
func TestNestedTextMarshaler(t *testing.T) {
|
||||||
var parent = struct {
|
var parent = struct {
|
||||||
Self textMarshaler `toml:"me"`
|
Self textMarshaler `toml:"me"`
|
||||||
@@ -1002,7 +1025,7 @@ type customPointerMarshaler struct {
|
|||||||
LastName string
|
LastName string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *customPointerMarshaler) MarshalText() ([]byte, error) {
|
func (m *customPointerMarshaler) MarshalTOML() ([]byte, error) {
|
||||||
return []byte("hidden"), nil
|
return []byte("hidden"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1048,6 +1071,30 @@ stranger = "hidden"
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPointerCustomMarshalerSequence(t *testing.T) {
|
||||||
|
var customPointerMarshalerSlice *[]*customPointerMarshaler
|
||||||
|
var customPointerMarshalerArray *[2]*customPointerMarshaler
|
||||||
|
|
||||||
|
if !isCustomMarshalerSequence(reflect.TypeOf(customPointerMarshalerSlice)) {
|
||||||
|
t.Errorf("error: should be a sequence of custom marshaler interfaces")
|
||||||
|
}
|
||||||
|
if !isCustomMarshalerSequence(reflect.TypeOf(customPointerMarshalerArray)) {
|
||||||
|
t.Errorf("error: should be a sequence of custom marshaler interfaces")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPointerTextMarshalerSequence(t *testing.T) {
|
||||||
|
var textPointerMarshalerSlice *[]*textPointerMarshaler
|
||||||
|
var textPointerMarshalerArray *[2]*textPointerMarshaler
|
||||||
|
|
||||||
|
if !isTextMarshalerSequence(reflect.TypeOf(textPointerMarshalerSlice)) {
|
||||||
|
t.Errorf("error: should be a sequence of text marshaler interfaces")
|
||||||
|
}
|
||||||
|
if !isTextMarshalerSequence(reflect.TypeOf(textPointerMarshalerArray)) {
|
||||||
|
t.Errorf("error: should be a sequence of text marshaler interfaces")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var commentTestToml = []byte(`
|
var commentTestToml = []byte(`
|
||||||
# it's a comment on type
|
# it's a comment on type
|
||||||
[postgres]
|
[postgres]
|
||||||
|
|||||||
Reference in New Issue
Block a user