Encoder: try to use pointer type TextMarshaler (#679)

If a type does not implement the encoding.TextMarshaler interface but
its pointer type does, use it if possible.

Fixes #678
This commit is contained in:
Thomas Pelletier
2021-11-24 14:43:49 -05:00
committed by GitHub
parent 8645d6376b
commit 2b3de620e8
3 changed files with 80 additions and 25 deletions
+7 -2
View File
@@ -209,7 +209,12 @@ func (enc *Encoder) encode(b []byte, ctx encoderCtx, v reflect.Value) ([]byte, e
}
}
if v.Type().Implements(textMarshalerType) {
hasTextMarshaler := v.Type().Implements(textMarshalerType)
if hasTextMarshaler || (v.CanAddr() && reflect.PtrTo(v.Type()).Implements(textMarshalerType)) {
if !hasTextMarshaler {
v = v.Addr()
}
if ctx.isRoot() {
return nil, fmt.Errorf("toml: type %s implementing the TextMarshaler interface cannot be a root element", v.Type())
}
@@ -657,7 +662,7 @@ func willConvertToTable(ctx encoderCtx, v reflect.Value) bool {
if !v.IsValid() {
return false
}
if v.Type() == timeType || v.Type().Implements(textMarshalerType) {
if v.Type() == timeType || v.Type().Implements(textMarshalerType) || (v.Kind() != reflect.Ptr && v.CanAddr() && reflect.PtrTo(v.Type()).Implements(textMarshalerType)) {
return false
}