diff --git a/marshal.go b/marshal.go index 0b9c08f..b2027cb 100644 --- a/marshal.go +++ b/marshal.go @@ -91,6 +91,13 @@ func (p *Encoder) marshalTime(val reflect.Value) cfValue { return cfDate(time) } +func innermostValue(val reflect.Value) reflect.Value { + for val.Kind() == reflect.Ptr || (val.Kind() == reflect.Interface && val.NumMethod() == 0) { + val = val.Elem() + } + return val +} + func (p *Encoder) marshal(val reflect.Value) cfValue { if !val.IsValid() { return nil @@ -105,7 +112,7 @@ func (p *Encoder) marshal(val reflect.Value) cfValue { return p.marshalTime(val) } if val.Kind() == reflect.Ptr || (val.Kind() == reflect.Interface && val.NumMethod() == 0) { - ival := val.Elem() + ival := innermostValue(val) if ival.IsValid() && ival.Type() == timeType { return p.marshalTime(ival) } diff --git a/marshal_test.go b/marshal_test.go index 4509909..28c2141 100644 --- a/marshal_test.go +++ b/marshal_test.go @@ -103,3 +103,26 @@ func TestInterfaceFieldMarshal(t *testing.T) { t.Log("expect non-zero data") } } + +func TestMarshalInterfaceFieldPtrTime(t *testing.T) { + type X struct { + C interface{} // C's type is unknown + } + + var sentinelTime = time.Date(2013, 11, 27, 0, 34, 0, 0, time.UTC) + x := &X{ + C: &sentinelTime, + } + + e := &Encoder{} + rval := reflect.ValueOf(x) + cf := e.marshal(rval) + + if dict, ok := cf.(*cfDictionary); ok { + if _, ok := dict.values[0].(cfDate); !ok { + t.Error("inner value is not a cfDate") + } + } else { + t.Error("failed to marshal toplevel dictionary (?)") + } +}