Recognize TextUnmarshaler and use it
This change recognizes TextUnmarshaler during object mapping, and will defer to it when we have a string but are assigning to a non-string target that implements the interface.
This commit is contained in:
parent
2f60a414c7
commit
1bdd24395c
1 changed files with 14 additions and 0 deletions
|
@ -3,6 +3,7 @@
|
||||||
package mapper
|
package mapper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -161,6 +162,7 @@ func (md *mapper) DecodeField(tree Object, ty reflect.Type, key string, target i
|
||||||
}
|
}
|
||||||
|
|
||||||
var emptyObject map[string]interface{}
|
var emptyObject map[string]interface{}
|
||||||
|
var textUnmarshalerType = reflect.TypeOf(new(encoding.TextUnmarshaler)).Elem()
|
||||||
|
|
||||||
// adjustValue converts if possible to produce the target type.
|
// adjustValue converts if possible to produce the target type.
|
||||||
func (md *mapper) adjustValue(val reflect.Value, to reflect.Type, ty reflect.Type, key string) (reflect.Value, error) {
|
func (md *mapper) adjustValue(val reflect.Value, to reflect.Type, ty reflect.Type, key string) (reflect.Value, error) {
|
||||||
|
@ -264,6 +266,18 @@ func (md *mapper) adjustValue(val reflect.Value, to reflect.Type, ty reflect.Typ
|
||||||
return val, fmt.Errorf(
|
return val, fmt.Errorf(
|
||||||
"Cannot decode Object to type %v; it isn't a struct, and no custom decoder exists", to)
|
"Cannot decode Object to type %v; it isn't a struct, and no custom decoder exists", to)
|
||||||
}
|
}
|
||||||
|
} else if val.Type().Kind() == reflect.String {
|
||||||
|
// If the source is a string, see if the target implements encoding.TextUnmarshaler.
|
||||||
|
target := reflect.New(to)
|
||||||
|
if target.Type().Implements(textUnmarshalerType) {
|
||||||
|
um := target.Interface().(encoding.TextUnmarshaler)
|
||||||
|
if err := um.UnmarshalText([]byte(val.String())); err != nil {
|
||||||
|
return val, err
|
||||||
|
}
|
||||||
|
val = target.Elem()
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue