@@ -224,6 +224,14 @@ type Marshaler interface {
224224MarshalJSON () ([]byte , error )
225225}
226226
227+ type RedirectMarshaler interface {
228+ RedirectMarshalJSON () (any , error )
229+ }
230+
231+ type TrustMarshaler interface {
232+ TrustMarshalJSON (b * bytes.Buffer ) error
233+ }
234+
227235// An UnsupportedTypeError is returned by Marshal when attempting
228236// to encode an unsupported value type.
229237type UnsupportedTypeError struct {
@@ -406,13 +414,21 @@ func typeEncoder(t reflect.Type) encoderFunc {
406414}
407415
408416var (
409- marshalerType = reflect .TypeOf ((* Marshaler )(nil )).Elem ()
410- textMarshalerType = reflect .TypeOf ((* encoding .TextMarshaler )(nil )).Elem ()
417+ marshalerType = reflect .TypeOf ((* Marshaler )(nil )).Elem ()
418+ redirMarshalerType = reflect .TypeOf ((* RedirectMarshaler )(nil )).Elem ()
419+ trustMarshalerType = reflect .TypeOf ((* TrustMarshaler )(nil )).Elem ()
420+ textMarshalerType = reflect .TypeOf ((* encoding .TextMarshaler )(nil )).Elem ()
411421)
412422
413423// newTypeEncoder constructs an encoderFunc for a type.
414424// The returned encoder only checks CanAddr when allowAddr is true.
415425func newTypeEncoder (t reflect.Type , allowAddr bool ) encoderFunc {
426+ if t .Implements (redirMarshalerType ) {
427+ return redirMarshalerEncoder
428+ }
429+ if t .Implements (trustMarshalerType ) {
430+ return marshalerTrustEncoder
431+ }
416432// If we have a non-pointer value whose type implements
417433// Marshaler with a value receiver, then we're better off taking
418434// the address of the value - otherwise we end up with an
@@ -464,6 +480,46 @@ func invalidValueEncoder(e *encodeState, v reflect.Value, _ encOpts) {
464480e .WriteString ("null" )
465481}
466482
483+ func redirMarshalerEncoder (e * encodeState , v reflect.Value , opts encOpts ) {
484+ if v .Kind () == reflect .Pointer && v .IsNil () {
485+ e .WriteString ("null" )
486+ return
487+ }
488+ m , ok := v .Interface ().(RedirectMarshaler )
489+ if ! ok {
490+ e .WriteString ("null" )
491+ return
492+ }
493+
494+ iv , err := m .RedirectMarshalJSON ()
495+ if err != nil {
496+ e .error (& MarshalerError {v .Type (), err , "RedirectMarshalJSON" })
497+ return
498+ }
499+
500+ e .marshal (iv , opts )
501+ }
502+
503+ func marshalerTrustEncoder (e * encodeState , v reflect.Value , opts encOpts ) {
504+ if v .Kind () == reflect .Pointer && v .IsNil () {
505+ e .WriteString ("null" )
506+ return
507+ }
508+ m , ok := v .Interface ().(TrustMarshaler )
509+ if ! ok {
510+ e .WriteString ("null" )
511+ return
512+ }
513+ err := m .TrustMarshalJSON (& e .Buffer )
514+ if err == nil {
515+ //_, err = e.Buffer.Write(b)
516+ // copy JSON into buffer, checking validity.
517+ //err = compact(&e.Buffer, b, opts.escapeHTML)
518+ }
519+ if err != nil {
520+ e .error (& MarshalerError {v .Type (), err , "MarshalJSON" })
521+ }
522+ }
467523func marshalerEncoder (e * encodeState , v reflect.Value , opts encOpts ) {
468524if v .Kind () == reflect .Pointer && v .IsNil () {
469525e .WriteString ("null" )
0 commit comments