diff --git a/marshal.go b/marshal.go index 0b9c08f..f31bf2c 100644 --- a/marshal.go +++ b/marshal.go @@ -186,6 +186,20 @@ func (p *Encoder) marshal(val reflect.Value) cfValue { } } return dict + case reflect.Interface, reflect.Ptr: + // Attempt to marshal the underlying type of the interface + if val.CanInterface() { + if inter := val.Interface(); inter != nil { + // Pointer to interface + interptr := reflect.New(reflect.TypeOf(inter)) + // Elem requires an Interface or Pointer + if elem := interptr.Elem(); elem.IsValid() && elem.CanSet() { + elem.Set(reflect.ValueOf(inter)) + return p.marshal(reflect.Indirect(interptr)) + } + } + } + panic(&unknownTypeError{typ}) default: panic(&unknownTypeError{typ}) } diff --git a/marshal_test.go b/marshal_test.go index 4509909..cd83777 100644 --- a/marshal_test.go +++ b/marshal_test.go @@ -103,3 +103,33 @@ func TestInterfaceFieldMarshal(t *testing.T) { t.Log("expect non-zero data") } } + +type Dog struct { + Name string +} + +type Animal interface{} + +func TestInterfaceSliceMarshal(t *testing.T) { + x := make([]Animal, 0) + x = append(x, &Dog{Name: "dog"}) + + b, err := Marshal(x, XMLFormat) + if err != nil { + t.Error(err) + } else if len(b) == 0 { + t.Error("expect non-zero data") + } +} + +func TestInterfaceGeneralSliceMarshal(t *testing.T) { + x := make([]interface{}, 0) // accept any type + x = append(x, &Dog{Name: "dog"}, "a string", 1, true) + + b, err := Marshal(x, XMLFormat) + if err != nil { + t.Error(err) + } else if len(b) == 0 { + t.Error("expect non-zero data") + } +}