@@ -416,12 +416,6 @@ func (p *printer) popPrefix() {
416
416
}
417
417
}
418
418
419
- var (
420
- marshalerType = reflect .TypeFor [Marshaler ]()
421
- marshalerAttrType = reflect .TypeFor [MarshalerAttr ]()
422
- textMarshalerType = reflect .TypeFor [encoding.TextMarshaler ]()
423
- )
424
-
425
419
// marshalValue writes one or more XML elements representing val.
426
420
// If val was obtained from a struct field, finfo must have its details.
427
421
func (p * printer ) marshalValue (val reflect.Value , finfo * fieldInfo , startTemplate * StartElement ) error {
@@ -450,24 +444,32 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
450
444
typ := val .Type ()
451
445
452
446
// Check for marshaler.
453
- if val .CanInterface () && typ .Implements (marshalerType ) {
454
- return p .marshalInterface (val .Interface ().(Marshaler ), defaultStart (typ , finfo , startTemplate ))
447
+ if val .CanInterface () {
448
+ if marshaler , ok := reflect.TypeAssert [Marshaler ](val ); ok {
449
+ return p .marshalInterface (marshaler , defaultStart (typ , finfo , startTemplate ))
450
+ }
455
451
}
456
452
if val .CanAddr () {
457
453
pv := val .Addr ()
458
- if pv .CanInterface () && pv .Type ().Implements (marshalerType ) {
459
- return p .marshalInterface (pv .Interface ().(Marshaler ), defaultStart (pv .Type (), finfo , startTemplate ))
454
+ if pv .CanInterface () {
455
+ if marshaler , ok := reflect.TypeAssert [Marshaler ](pv ); ok {
456
+ return p .marshalInterface (marshaler , defaultStart (pv .Type (), finfo , startTemplate ))
457
+ }
460
458
}
461
459
}
462
460
463
461
// Check for text marshaler.
464
- if val .CanInterface () && typ .Implements (textMarshalerType ) {
465
- return p .marshalTextInterface (val .Interface ().(encoding.TextMarshaler ), defaultStart (typ , finfo , startTemplate ))
462
+ if val .CanInterface () {
463
+ if textMarshaler , ok := reflect.TypeAssert [encoding.TextMarshaler ](val ); ok {
464
+ return p .marshalTextInterface (textMarshaler , defaultStart (typ , finfo , startTemplate ))
465
+ }
466
466
}
467
467
if val .CanAddr () {
468
468
pv := val .Addr ()
469
- if pv .CanInterface () && pv .Type ().Implements (textMarshalerType ) {
470
- return p .marshalTextInterface (pv .Interface ().(encoding.TextMarshaler ), defaultStart (pv .Type (), finfo , startTemplate ))
469
+ if pv .CanInterface () {
470
+ if textMarshaler , ok := reflect.TypeAssert [encoding.TextMarshaler ](pv ); ok {
471
+ return p .marshalTextInterface (textMarshaler , defaultStart (pv .Type (), finfo , startTemplate ))
472
+ }
471
473
}
472
474
}
473
475
@@ -503,7 +505,7 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
503
505
start .Name .Space , start .Name .Local = xmlname .xmlns , xmlname .name
504
506
} else {
505
507
fv := xmlname .value (val , dontInitNilPointers )
506
- if v , ok := fv . Interface ().( Name ); ok && v .Local != "" {
508
+ if v , ok := reflect. TypeAssert [ Name ]( fv ); ok && v .Local != "" {
507
509
start .Name = v
508
510
}
509
511
}
@@ -580,21 +582,9 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
580
582
581
583
// marshalAttr marshals an attribute with the given name and value, adding to start.Attr.
582
584
func (p * printer ) marshalAttr (start * StartElement , name Name , val reflect.Value ) error {
583
- if val .CanInterface () && val .Type ().Implements (marshalerAttrType ) {
584
- attr , err := val .Interface ().(MarshalerAttr ).MarshalXMLAttr (name )
585
- if err != nil {
586
- return err
587
- }
588
- if attr .Name .Local != "" {
589
- start .Attr = append (start .Attr , attr )
590
- }
591
- return nil
592
- }
593
-
594
- if val .CanAddr () {
595
- pv := val .Addr ()
596
- if pv .CanInterface () && pv .Type ().Implements (marshalerAttrType ) {
597
- attr , err := pv .Interface ().(MarshalerAttr ).MarshalXMLAttr (name )
585
+ if val .CanInterface () {
586
+ if marshaler , ok := reflect.TypeAssert [MarshalerAttr ](val ); ok {
587
+ attr , err := marshaler .MarshalXMLAttr (name )
598
588
if err != nil {
599
589
return err
600
590
}
@@ -605,19 +595,25 @@ func (p *printer) marshalAttr(start *StartElement, name Name, val reflect.Value)
605
595
}
606
596
}
607
597
608
- if val .CanInterface () && val .Type ().Implements (textMarshalerType ) {
609
- text , err := val .Interface ().(encoding.TextMarshaler ).MarshalText ()
610
- if err != nil {
611
- return err
598
+ if val .CanAddr () {
599
+ pv := val .Addr ()
600
+ if pv .CanInterface () {
601
+ if marshaler , ok := reflect.TypeAssert [MarshalerAttr ](pv ); ok {
602
+ attr , err := marshaler .MarshalXMLAttr (name )
603
+ if err != nil {
604
+ return err
605
+ }
606
+ if attr .Name .Local != "" {
607
+ start .Attr = append (start .Attr , attr )
608
+ }
609
+ return nil
610
+ }
612
611
}
613
- start .Attr = append (start .Attr , Attr {name , string (text )})
614
- return nil
615
612
}
616
613
617
- if val .CanAddr () {
618
- pv := val .Addr ()
619
- if pv .CanInterface () && pv .Type ().Implements (textMarshalerType ) {
620
- text , err := pv .Interface ().(encoding.TextMarshaler ).MarshalText ()
614
+ if val .CanInterface () {
615
+ if textMarshaler , ok := reflect.TypeAssert [encoding.TextMarshaler ](val ); ok {
616
+ text , err := textMarshaler .MarshalText ()
621
617
if err != nil {
622
618
return err
623
619
}
@@ -626,6 +622,20 @@ func (p *printer) marshalAttr(start *StartElement, name Name, val reflect.Value)
626
622
}
627
623
}
628
624
625
+ if val .CanAddr () {
626
+ pv := val .Addr ()
627
+ if pv .CanInterface () {
628
+ if textMarshaler , ok := reflect.TypeAssert [encoding.TextMarshaler ](pv ); ok {
629
+ text , err := textMarshaler .MarshalText ()
630
+ if err != nil {
631
+ return err
632
+ }
633
+ start .Attr = append (start .Attr , Attr {name , string (text )})
634
+ return nil
635
+ }
636
+ }
637
+ }
638
+
629
639
// Dereference or skip nil pointer, interface values.
630
640
switch val .Kind () {
631
641
case reflect .Pointer , reflect .Interface :
@@ -647,7 +657,8 @@ func (p *printer) marshalAttr(start *StartElement, name Name, val reflect.Value)
647
657
}
648
658
649
659
if val .Type () == attrType {
650
- start .Attr = append (start .Attr , val .Interface ().(Attr ))
660
+ attr , _ := reflect.TypeAssert [Attr ](val )
661
+ start .Attr = append (start .Attr , attr )
651
662
return nil
652
663
}
653
664
@@ -854,20 +865,9 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
854
865
if err := s .trim (finfo .parents ); err != nil {
855
866
return err
856
867
}
857
- if vf .CanInterface () && vf .Type ().Implements (textMarshalerType ) {
858
- data , err := vf .Interface ().(encoding.TextMarshaler ).MarshalText ()
859
- if err != nil {
860
- return err
861
- }
862
- if err := emit (p , data ); err != nil {
863
- return err
864
- }
865
- continue
866
- }
867
- if vf .CanAddr () {
868
- pv := vf .Addr ()
869
- if pv .CanInterface () && pv .Type ().Implements (textMarshalerType ) {
870
- data , err := pv .Interface ().(encoding.TextMarshaler ).MarshalText ()
868
+ if vf .CanInterface () {
869
+ if textMarshaler , ok := reflect.TypeAssert [encoding.TextMarshaler ](vf ); ok {
870
+ data , err := textMarshaler .MarshalText ()
871
871
if err != nil {
872
872
return err
873
873
}
@@ -877,6 +877,21 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
877
877
continue
878
878
}
879
879
}
880
+ if vf .CanAddr () {
881
+ pv := vf .Addr ()
882
+ if pv .CanInterface () {
883
+ if textMarshaler , ok := reflect.TypeAssert [encoding.TextMarshaler ](pv ); ok {
884
+ data , err := textMarshaler .MarshalText ()
885
+ if err != nil {
886
+ return err
887
+ }
888
+ if err := emit (p , data ); err != nil {
889
+ return err
890
+ }
891
+ continue
892
+ }
893
+ }
894
+ }
880
895
881
896
var scratch [64 ]byte
882
897
vf = indirect (vf )
@@ -902,7 +917,7 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
902
917
return err
903
918
}
904
919
case reflect .Slice :
905
- if elem , ok := vf . Interface ().([ ]byte ); ok {
920
+ if elem , ok := reflect. TypeAssert [[ ]byte ]( vf ); ok {
906
921
if err := emit (p , elem ); err != nil {
907
922
return err
908
923
}
0 commit comments