aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/xml/read.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/encoding/xml/read.go')
-rw-r--r--src/encoding/xml/read.go77
1 files changed, 46 insertions, 31 deletions
diff --git a/src/encoding/xml/read.go b/src/encoding/xml/read.go
index af25c20f06..d3cb74b2c4 100644
--- a/src/encoding/xml/read.go
+++ b/src/encoding/xml/read.go
@@ -255,28 +255,36 @@ func (d *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error {
}
val = val.Elem()
}
- if val.CanInterface() && val.Type().Implements(unmarshalerAttrType) {
+ if val.CanInterface() {
// This is an unmarshaler with a non-pointer receiver,
// so it's likely to be incorrect, but we do what we're told.
- return val.Interface().(UnmarshalerAttr).UnmarshalXMLAttr(attr)
+ if unmarshaler, ok := reflect.TypeAssert[UnmarshalerAttr](val); ok {
+ return unmarshaler.UnmarshalXMLAttr(attr)
+ }
}
if val.CanAddr() {
pv := val.Addr()
- if pv.CanInterface() && pv.Type().Implements(unmarshalerAttrType) {
- return pv.Interface().(UnmarshalerAttr).UnmarshalXMLAttr(attr)
+ if pv.CanInterface() {
+ if unmarshaler, ok := reflect.TypeAssert[UnmarshalerAttr](pv); ok {
+ return unmarshaler.UnmarshalXMLAttr(attr)
+ }
}
}
// Not an UnmarshalerAttr; try encoding.TextUnmarshaler.
- if val.CanInterface() && val.Type().Implements(textUnmarshalerType) {
+ if val.CanInterface() {
// This is an unmarshaler with a non-pointer receiver,
// so it's likely to be incorrect, but we do what we're told.
- return val.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(attr.Value))
+ if textUnmarshaler, ok := reflect.TypeAssert[encoding.TextUnmarshaler](val); ok {
+ return textUnmarshaler.UnmarshalText([]byte(attr.Value))
+ }
}
if val.CanAddr() {
pv := val.Addr()
- if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) {
- return pv.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(attr.Value))
+ if pv.CanInterface() {
+ if textUnmarshaler, ok := reflect.TypeAssert[encoding.TextUnmarshaler](pv); ok {
+ return textUnmarshaler.UnmarshalText([]byte(attr.Value))
+ }
}
}
@@ -303,12 +311,7 @@ func (d *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error {
return copyValue(val, []byte(attr.Value))
}
-var (
- attrType = reflect.TypeFor[Attr]()
- unmarshalerType = reflect.TypeFor[Unmarshaler]()
- unmarshalerAttrType = reflect.TypeFor[UnmarshalerAttr]()
- textUnmarshalerType = reflect.TypeFor[encoding.TextUnmarshaler]()
-)
+var attrType = reflect.TypeFor[Attr]()
const (
maxUnmarshalDepth = 10000
@@ -352,27 +355,35 @@ func (d *Decoder) unmarshal(val reflect.Value, start *StartElement, depth int) e
val = val.Elem()
}
- if val.CanInterface() && val.Type().Implements(unmarshalerType) {
+ if val.CanInterface() {
// This is an unmarshaler with a non-pointer receiver,
// so it's likely to be incorrect, but we do what we're told.
- return d.unmarshalInterface(val.Interface().(Unmarshaler), start)
+ if unmarshaler, ok := reflect.TypeAssert[Unmarshaler](val); ok {
+ return d.unmarshalInterface(unmarshaler, start)
+ }
}
if val.CanAddr() {
pv := val.Addr()
- if pv.CanInterface() && pv.Type().Implements(unmarshalerType) {
- return d.unmarshalInterface(pv.Interface().(Unmarshaler), start)
+ if pv.CanInterface() {
+ if unmarshaler, ok := reflect.TypeAssert[Unmarshaler](pv); ok {
+ return d.unmarshalInterface(unmarshaler, start)
+ }
}
}
- if val.CanInterface() && val.Type().Implements(textUnmarshalerType) {
- return d.unmarshalTextInterface(val.Interface().(encoding.TextUnmarshaler))
+ if val.CanInterface() {
+ if textUnmarshaler, ok := reflect.TypeAssert[encoding.TextUnmarshaler](val); ok {
+ return d.unmarshalTextInterface(textUnmarshaler)
+ }
}
if val.CanAddr() {
pv := val.Addr()
- if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) {
- return d.unmarshalTextInterface(pv.Interface().(encoding.TextUnmarshaler))
+ if pv.CanInterface() {
+ if textUnmarshaler, ok := reflect.TypeAssert[encoding.TextUnmarshaler](pv); ok {
+ return d.unmarshalTextInterface(textUnmarshaler)
+ }
}
}
@@ -453,7 +464,7 @@ func (d *Decoder) unmarshal(val reflect.Value, start *StartElement, depth int) e
return UnmarshalError(e)
}
fv := finfo.value(sv, initNilPointers)
- if _, ok := fv.Interface().(Name); ok {
+ if _, ok := reflect.TypeAssert[Name](fv); ok {
fv.Set(reflect.ValueOf(start.Name))
}
}
@@ -578,20 +589,24 @@ Loop:
}
}
- if saveData.IsValid() && saveData.CanInterface() && saveData.Type().Implements(textUnmarshalerType) {
- if err := saveData.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil {
- return err
+ if saveData.IsValid() && saveData.CanInterface() {
+ if textUnmarshaler, ok := reflect.TypeAssert[encoding.TextUnmarshaler](saveData); ok {
+ if err := textUnmarshaler.UnmarshalText(data); err != nil {
+ return err
+ }
+ saveData = reflect.Value{}
}
- saveData = reflect.Value{}
}
if saveData.IsValid() && saveData.CanAddr() {
pv := saveData.Addr()
- if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) {
- if err := pv.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil {
- return err
+ if pv.CanInterface() {
+ if textUnmarshaler, ok := reflect.TypeAssert[encoding.TextUnmarshaler](pv); ok {
+ if err := textUnmarshaler.UnmarshalText(data); err != nil {
+ return err
+ }
+ saveData = reflect.Value{}
}
- saveData = reflect.Value{}
}
}