github.com/trim21/go-phpserialize@v0.0.22-0.20240301204449-2fca0319b3f0/internal/encoder/ptr.go (about) 1 package encoder 2 3 import ( 4 "fmt" 5 "reflect" 6 7 "github.com/trim21/go-phpserialize/internal/runtime" 8 ) 9 10 // MUST call `compilePtr` directly when compile encoder for struct field. 11 func compilePtr(rt *runtime.Type, seen seenMap) (encoder, error) { 12 switch rt.Elem().Kind() { 13 case reflect.Ptr: 14 return nil, fmt.Errorf("encoding nested ptr is not supported *%s", rt.Elem().String()) 15 16 case reflect.Bool: 17 return encodeBool, nil 18 case reflect.Uint8: 19 return encodeUint8, nil 20 case reflect.Uint16: 21 return encodeUint16, nil 22 case reflect.Uint32: 23 return encodeUint32, nil 24 case reflect.Uint64: 25 return encodeUint64, nil 26 case reflect.Uint: 27 return encodeUint, nil 28 case reflect.Int8: 29 return encodeInt8, nil 30 case reflect.Int16: 31 return encodeInt16, nil 32 case reflect.Int32: 33 return encodeInt32, nil 34 case reflect.Int64: 35 return encodeInt64, nil 36 case reflect.Int: 37 return encodeInt, nil 38 case reflect.Float32: 39 return encodeFloat32, nil 40 case reflect.Float64: 41 return encodeFloat64, nil 42 case reflect.String: 43 return encodeString, nil 44 case reflect.Interface: 45 return compileInterface(rt.Elem()) 46 case reflect.Map: 47 enc, err := compileMap(rt.Elem(), seen) 48 return deRefNilEncoder(enc), err 49 case reflect.Struct: 50 enc, err := compileStruct(rt.Elem(), seen) 51 indirect := runtime.IfaceIndir(rt.Elem()) 52 if indirect { 53 return wrapNilEncoder(enc), err 54 } 55 56 return deRefNilEncoder(enc), err 57 } 58 59 enc, err := compile(rt.Elem(), seen) 60 if err != nil { 61 return nil, err 62 } 63 64 return deRefNilEncoder(enc), nil 65 } 66 67 func deRefNilEncoder(enc encoder) encoder { 68 return func(ctx *Ctx, b []byte, p uintptr) ([]byte, error) { 69 if p == 0 { 70 return appendNull(b), nil 71 } 72 p = PtrDeRef(p) 73 return enc(ctx, b, p) 74 } 75 } 76 77 func wrapNilEncoder(enc encoder) encoder { 78 return func(ctx *Ctx, b []byte, p uintptr) ([]byte, error) { 79 if p == 0 { 80 return appendNull(b), nil 81 } 82 return enc(ctx, b, p) 83 } 84 }