github.com/urso/go-structform@v0.0.2/gotype/unfold_map.yml (about) 1 import: 2 - unfold_templates.yml 3 4 main: | 5 package gotype 6 7 import "github.com/urso/go-structform" 8 9 {{/* defined 'lifted' pointer map unfolders into reflection based unfolders */}} 10 var ( 11 unfolderReflMapIfc = liftGoUnfolder(newUnfolderMapIfc()) 12 {{ range data.primitiveTypes }} 13 {{ $t := capitalize . }} 14 unfolderReflMap{{ $t }} = liftGoUnfolder(newUnfolderMap{{ $t }}()) 15 {{ end }} 16 ) 17 18 {{/* define pointer based unfolder types */}} 19 {{ invoke "makeTypeWithName" "name" "Ifc" "type" "interface{}" }} 20 {{ template "makeType" "bool" }} 21 {{ template "makeType" "string" }} 22 {{ range .numTypes }} 23 {{ template "makeType" . }} 24 {{ end }} 25 26 {{/* create value visitor callbacks */}} 27 {{ invoke "onIfcFns" "name" "unfolderMapIfc" "fn" "put" }} 28 {{ invoke "onBoolFns" "name" "unfolderMapBool" "fn" "put" }} 29 {{ invoke "onStringFns" "name" "unfolderMapString" "fn" "put" }} 30 {{ range .numTypes }} 31 {{ $type := . }} 32 {{ $name := capitalize $type | printf "unfolderMap%v" }} 33 {{ invoke "onNumberFns" "name" $name "type" $type "fn" "put" }} 34 {{ end }} 35 36 {{ template "mapIfc" }} 37 38 39 # makeTypeWithName(name, type) 40 templates.makeTypeWithName: | 41 {{ $type := .type }} 42 {{ $name := capitalize .name | printf "unfolderMap%v" }} 43 {{ $startName := capitalize .name | printf "unfoldMapStart%v" }} 44 {{ $keyName := capitalize .name | printf "unfoldMapKey%v" }} 45 46 {{ invoke "makeUnfoldType" "name" $name }} 47 {{ invoke "makeUnfoldType" "name" $startName "base" "unfolderErrObjectStart" }} 48 {{ invoke "makeUnfoldType" "name" $keyName "base" "unfolderErrExpectKey" }} 49 50 func (u *{{ $name }} ) initState(ctx *unfoldCtx, ptr unsafe.Pointer) { 51 ctx.unfolder.push(new{{ $keyName | capitalize}}()) 52 ctx.unfolder.push(new{{ $startName | capitalize}}()) 53 ctx.ptr.push(ptr) 54 } 55 56 func (u * {{ $keyName }} ) cleanup(ctx *unfoldCtx) { 57 ctx.unfolder.pop() 58 ctx.ptr.pop() 59 } 60 61 func (u * {{ $startName }}) cleanup(ctx *unfoldCtx) { 62 ctx.unfolder.pop() 63 } 64 65 66 func (u *{{ $name }} ) ptr(ctx *unfoldCtx) *map[string]{{ $type }} { 67 return (*map[string]{{ $type }})(ctx.ptr.current) 68 } 69 70 71 func (u *{{ $startName }} ) OnObjectStart(ctx *unfoldCtx, l int, baseType structform.BaseType) error { 72 // TODO: validate baseType 73 74 u.cleanup(ctx) 75 return nil 76 } 77 78 func (u *{{ $keyName }} ) OnKeyRef(ctx *unfoldCtx, key []byte) error { 79 return u.OnKey(ctx, ctx.keyCache.get(key)) 80 } 81 82 func (u *{{ $keyName }} ) OnKey(ctx *unfoldCtx, key string) error { 83 ctx.key.push(key) 84 ctx.unfolder.current = new{{ $name | capitalize }}() 85 return nil 86 } 87 88 func (u *{{ $keyName }} ) OnObjectFinished(ctx *unfoldCtx) error { 89 u.cleanup(ctx) 90 return nil 91 } 92 93 func (u *{{ $name }} ) put(ctx *unfoldCtx, v {{ $type }}) error { 94 to := u.ptr(ctx) 95 if *to == nil { 96 *to = map[string]{{ $type }}{} 97 } 98 (*to)[ctx.key.pop()] = v 99 100 ctx.unfolder.current = new{{ $keyName | capitalize }}() 101 return nil 102 } 103 104 templates.mapIfc: | 105 func unfoldIfcStartSubMap(ctx *unfoldCtx, l int, baseType structform.BaseType) error { 106 _, ptr, unfolder := makeMapPtr(ctx, l, baseType) 107 ctx.ptr.push(ptr) 108 ctx.baseType.push(baseType) 109 unfolder.initState(ctx, ptr) 110 return ctx.unfolder.current.OnObjectStart(ctx, l, baseType) 111 } 112 113 func unfoldIfcFinishSubMap(ctx *unfoldCtx) (interface{}, error) { 114 child := ctx.ptr.pop() 115 bt := ctx.baseType.pop() 116 switch bt { 117 {{ range $bt, $gt := data.mapTypes }} 118 case structform.{{ $bt }}: 119 ctx.buf.release() 120 return *(*map[string]{{ $gt }})(child), nil 121 {{ end }} 122 default: 123 return nil, errTODO() 124 } 125 } 126 127 func makeMapPtr(ctx *unfoldCtx, l int, bt structform.BaseType) (interface{}, unsafe.Pointer, ptrUnfolder) { 128 switch bt { 129 {{ range $bt, $gt := data.mapTypes }} 130 case structform.{{ $bt }}: 131 sz := unsafe.Sizeof(map[string]{{ $gt }}{}) 132 ptr := ctx.buf.alloc(int(sz)) 133 to := (*map[string]{{ $gt }})(ptr) 134 {{ if or (eq $bt "AnyType") (eq $bt "ZeroType") }} 135 unfolder := newUnfolderMapIfc() 136 {{ else }} 137 unfolder := newUnfolderMap{{ $gt | capitalize }}() 138 {{ end }} 139 return to, ptr, unfolder 140 {{ end }} 141 default: 142 panic("invalid type code") 143 return nil, nil, nil 144 } 145 }