github.com/urso/go-structform@v0.0.2/gotype/unfold_lookup_go.yml (about) 1 import: 2 - unfold_templates.yml 3 4 main: | 5 package gotype 6 7 func lookupGoTypeUnfolder(to interface{}) (unsafe.Pointer, ptrUnfolder) { 8 switch ptr := to.(type) { 9 case *interface{}: 10 return unsafe.Pointer(ptr), newUnfolderIfc() 11 case *[]interface{}: 12 return unsafe.Pointer(ptr), newUnfolderArrIfc() 13 case *map[string]interface{}: 14 return unsafe.Pointer(ptr), newUnfolderMapIfc() 15 16 {{ range data.primitiveTypes }} 17 case *{{ . }}: 18 return unsafe.Pointer(ptr), newUnfolder{{ . | capitalize }}() 19 case *[]{{ . }}: 20 return unsafe.Pointer(ptr), newUnfolderArr{{ . | capitalize }}() 21 case *map[string]{{ . }}: 22 return unsafe.Pointer(ptr), newUnfolderMap{{ . | capitalize }}() 23 {{ end }} 24 default: 25 return nil, nil 26 } 27 } 28 29 func lookupGoPtrUnfolder(t reflect.Type) (ptrUnfolder) { 30 switch t.Kind() { 31 case reflect.Interface: 32 return newUnfolderIfc() 33 {{ range data.primitiveTypes }} 34 case reflect.{{ . | capitalize }}: 35 return newUnfolder{{ . | capitalize }}() 36 {{ end }} 37 38 case reflect.Slice: 39 et := t.Elem() 40 switch et.Kind() { 41 case reflect.Interface: 42 return newUnfolderArrIfc() 43 {{ range data.primitiveTypes }} 44 case reflect.{{ . | capitalize }}: 45 return newUnfolderArr{{ . | capitalize }}() 46 {{ end }} 47 } 48 49 case reflect.Map: 50 if t.Key().Kind() != reflect.String { 51 return nil 52 } 53 54 et := t.Elem() 55 switch et.Kind() { 56 case reflect.Interface: 57 return newUnfolderMapIfc() 58 {{ range data.primitiveTypes }} 59 case reflect.{{ . | capitalize }}: 60 return newUnfolderMap{{ . | capitalize }}() 61 {{ end }} 62 } 63 64 } 65 66 return nil 67 } 68 69 func lookupReflUnfolder(ctx *unfoldCtx, t reflect.Type) (reflUnfolder, error) { 70 if f := unfoldRegistry.find(t); f != nil { 71 return f, nil 72 } 73 74 f, err := buildReflUnfolder(ctx, t) 75 if err != nil { 76 return nil, err 77 } 78 79 unfoldRegistry.set(t, f) 80 return f, nil 81 } 82 83 func buildReflUnfolder(ctx *unfoldCtx, t reflect.Type) (reflUnfolder, error) { 84 // we always expect a pointer 85 bt := t.Elem() 86 87 switch bt.Kind() { 88 case reflect.Interface: 89 return unfolderReflIfc, nil 90 {{ range data.primitiveTypes }} 91 case reflect.{{ . | capitalize }}: 92 return unfolderRefl{{ . | capitalize }}, nil 93 {{ end }} 94 95 case reflect.Array: 96 return nil, errTODO() 97 98 case reflect.Ptr: 99 unfolderElem, err := lookupReflUnfolder(ctx, bt) 100 if err != nil { 101 return nil, err 102 } 103 return newUnfolderReflPtr(unfolderElem), nil 104 105 case reflect.Slice: 106 et := bt.Elem() 107 switch et.Kind() { 108 case reflect.Interface: 109 return unfolderReflArrIfc, nil 110 {{ range data.primitiveTypes }} 111 case reflect.{{ . | capitalize }}: 112 return unfolderReflArr{{ . | capitalize }}, nil 113 {{ end }} 114 } 115 116 unfolderElem, err := lookupReflUnfolder(ctx, reflect.PtrTo(et)) 117 if err != nil { 118 return nil, err 119 } 120 return newUnfolderReflSlice(unfolderElem), nil 121 122 case reflect.Map: 123 et := bt.Elem() 124 switch et.Kind() { 125 case reflect.Interface: 126 return unfolderReflMapIfc, nil 127 {{ range data.primitiveTypes }} 128 case reflect.{{ . | capitalize }}: 129 return unfolderReflMap{{ . | capitalize }}, nil 130 {{ end }} 131 } 132 133 unfolderElem, err := lookupReflUnfolder(ctx, reflect.PtrTo(et)) 134 if err != nil { 135 return nil, err 136 } 137 return newUnfolderReflMap(unfolderElem), nil 138 139 case reflect.Struct: 140 return createUnfolderReflStruct(ctx, t) 141 142 default: 143 return nil, errTODO() 144 } 145 }