github.com/hamba/avro@v1.8.0/codec_marshaler.go (about) 1 package avro 2 3 import ( 4 "encoding" 5 "unsafe" 6 7 "github.com/modern-go/reflect2" 8 ) 9 10 var ( 11 textMarshalerType = reflect2.TypeOfPtr((*encoding.TextMarshaler)(nil)).Elem() 12 textUnmarshalerType = reflect2.TypeOfPtr((*encoding.TextUnmarshaler)(nil)).Elem() 13 ) 14 15 func createDecoderOfMarshaler(_ *frozenConfig, schema Schema, typ reflect2.Type) ValDecoder { 16 if typ.Implements(textUnmarshalerType) && schema.Type() == String { 17 return &textMarshalerCodec{typ} 18 } 19 ptrType := reflect2.PtrTo(typ) 20 if ptrType.Implements(textUnmarshalerType) && schema.Type() == String { 21 return &referenceDecoder{ 22 &textMarshalerCodec{ptrType}, 23 } 24 } 25 return nil 26 } 27 28 func createEncoderOfMarshaler(_ *frozenConfig, schema Schema, typ reflect2.Type) ValEncoder { 29 if typ.Implements(textMarshalerType) && schema.Type() == String { 30 return &textMarshalerCodec{ 31 typ: typ, 32 } 33 } 34 return nil 35 } 36 37 type textMarshalerCodec struct { 38 typ reflect2.Type 39 } 40 41 func (c textMarshalerCodec) Decode(ptr unsafe.Pointer, r *Reader) { 42 obj := c.typ.UnsafeIndirect(ptr) 43 if reflect2.IsNil(obj) { 44 ptrType := c.typ.(*reflect2.UnsafePtrType) 45 newPtr := ptrType.Elem().UnsafeNew() 46 *((*unsafe.Pointer)(ptr)) = newPtr 47 obj = c.typ.UnsafeIndirect(ptr) 48 } 49 unmarshaler := (obj).(encoding.TextUnmarshaler) 50 b := r.ReadBytes() 51 err := unmarshaler.UnmarshalText(b) 52 if err != nil { 53 r.ReportError("textMarshalerCodec", err.Error()) 54 } 55 } 56 57 func (c textMarshalerCodec) Encode(ptr unsafe.Pointer, w *Writer) { 58 obj := c.typ.UnsafeIndirect(ptr) 59 if c.typ.IsNullable() && reflect2.IsNil(obj) { 60 w.WriteBytes(nil) 61 return 62 } 63 marshaler := (obj).(encoding.TextMarshaler) 64 b, err := marshaler.MarshalText() 65 if err != nil { 66 w.Error = err 67 return 68 } 69 w.WriteBytes(b) 70 }