github.com/trim21/go-phpserialize@v0.0.22-0.20240301204449-2fca0319b3f0/internal/encoder/compile.go (about) 1 package encoder 2 3 import ( 4 "fmt" 5 "reflect" 6 "unsafe" 7 8 "github.com/trim21/go-phpserialize/internal/runtime" 9 ) 10 11 type encoder func(ctx *Ctx, b []byte, p uintptr) ([]byte, error) 12 13 func compileTypeID(typeID uintptr) (encoder, error) { 14 rt := *(**runtime.Type)(unsafe.Pointer(&typeID)) 15 16 return compile(rt, seenMap{}) 17 } 18 19 func compile(rt *runtime.Type, seen seenMap) (encoder, error) { 20 switch rt.Kind() { 21 case reflect.Bool: 22 return encodeBool, nil 23 case reflect.Int8: 24 return encodeInt8, nil 25 case reflect.Int16: 26 return encodeInt16, nil 27 case reflect.Int32: 28 return encodeInt32, nil 29 case reflect.Int64: 30 return encodeInt64, nil 31 case reflect.Int: 32 return encodeInt, nil 33 case reflect.Uint8: 34 return encodeUint8, nil 35 case reflect.Uint16: 36 return encodeUint16, nil 37 case reflect.Uint32: 38 return encodeUint32, nil 39 case reflect.Uint64: 40 return encodeUint64, nil 41 case reflect.Uint: 42 return encodeUint, nil 43 case reflect.Float32: 44 return encodeFloat32, nil 45 case reflect.Float64: 46 return encodeFloat64, nil 47 case reflect.String: 48 return encodeString, nil 49 case reflect.Struct: 50 return compileStruct(rt, seen) 51 case reflect.Array: 52 return compileArray(rt) 53 case reflect.Slice: 54 return compileSlice(rt, seen) 55 case reflect.Map: 56 return compileMap(rt, seen) 57 case reflect.Interface: 58 return compileInterface(rt) 59 case reflect.Ptr: 60 return compilePtr(rt, seen) 61 } 62 63 return nil, fmt.Errorf("failed to build encoder, unsupported type %s (kind %s)", rt.String(), rt.Kind()) 64 } 65 66 func compileMapKey(typ *runtime.Type) (encoder, error) { 67 switch typ.Kind() { 68 case reflect.String: 69 return encodeString, nil 70 71 case reflect.Int8: 72 return encodeInt8, nil 73 case reflect.Int16: 74 return encodeInt16, nil 75 case reflect.Int32: 76 return encodeInt32, nil 77 case reflect.Int64: 78 return encodeInt64, nil 79 case reflect.Int: 80 return encodeInt, nil 81 case reflect.Uint8: 82 return encodeUint8, nil 83 case reflect.Uint16: 84 return encodeUint16, nil 85 case reflect.Uint32: 86 return encodeUint32, nil 87 case reflect.Uint64: 88 return encodeUint64, nil 89 case reflect.Uint: 90 return encodeUint, nil 91 } 92 93 return nil, fmt.Errorf("failed to build encoder for map key, unsupported type %s (kind %s)", typ.String(), typ.Kind()) 94 } 95 96 func compileAsString(rt *runtime.Type) (encoder, error) { 97 switch rt.Kind() { 98 case reflect.Bool: 99 return compileBoolAsString(rt) 100 case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: 101 return compileIntAsString(rt) 102 case reflect.String: 103 return encodeString, nil 104 case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: 105 return compileUintAsString(rt) 106 case reflect.Float32, reflect.Float64: 107 return compileFloatAsString(rt) 108 case reflect.Interface: 109 return compileInterfaceAsString(rt) 110 } 111 112 return nil, fmt.Errorf( 113 "failed to build encoder for struct field (as string), unsupported type %s (kind %s)", 114 rt.String(), rt.Kind()) 115 }