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  }