diff --git a/util/gconv/gconv_interface.go b/util/gconv/gconv_interface.go index cce763cc0..9c23f9425 100644 --- a/util/gconv/gconv_interface.go +++ b/util/gconv/gconv_interface.go @@ -90,6 +90,12 @@ type apiUnmarshalText interface { UnmarshalText(text []byte) error } +// apiUnmarshalText is the interface for custom defined types customizing value assignment. +// Note that only pointer can implement interface apiUnmarshalJSON. +type apiUnmarshalJSON interface { + UnmarshalJSON(b []byte) error +} + // apiSet is the interface for custom value assignment. type apiSet interface { Set(value interface{}) (old interface{}) diff --git a/util/gconv/gconv_struct.go b/util/gconv/gconv_struct.go index 78649056c..76ee3abb9 100644 --- a/util/gconv/gconv_struct.go +++ b/util/gconv/gconv_struct.go @@ -355,6 +355,15 @@ func bindVarToReflectValueWithInterfaceCheck(reflectValue reflect.Value, value i return v.UnmarshalText(b), ok } } + // UnmarshalJSON. + if v, ok := pointer.(apiUnmarshalJSON); ok { + if s, ok := value.(string); ok { + return v.UnmarshalJSON([]byte(s)), ok + } + if b, ok := value.([]byte); ok { + return v.UnmarshalJSON(b), ok + } + } if v, ok := pointer.(apiSet); ok { v.Set(value) return nil, ok