github.com/galaxy-book/gqlgen@v0.7.2/codegen/type.go (about) 1 package codegen 2 3 import ( 4 "strconv" 5 "strings" 6 7 "github.com/99designs/gqlgen/codegen/templates" 8 9 "github.com/vektah/gqlparser/ast" 10 ) 11 12 type NamedTypes map[string]*NamedType 13 14 type NamedType struct { 15 Ref 16 IsScalar bool 17 IsInterface bool 18 IsInput bool 19 GQLType string // Name of the graphql type 20 Marshaler *Ref // If this type has an external marshaler this will be set 21 } 22 23 type Ref struct { 24 GoType string // Name of the go type 25 Package string // the package the go type lives in 26 IsUserDefined bool // does the type exist in the typemap 27 } 28 29 type Type struct { 30 *NamedType 31 32 Modifiers []string 33 ASTType *ast.Type 34 AliasedType *Ref 35 } 36 37 const ( 38 modList = "[]" 39 modPtr = "*" 40 ) 41 42 func (t Ref) FullName() string { 43 return t.PkgDot() + t.GoType 44 } 45 46 func (t Ref) PkgDot() string { 47 name := templates.CurrentImports.Lookup(t.Package) 48 if name == "" { 49 return "" 50 51 } 52 53 return name + "." 54 } 55 56 func (t Type) Signature() string { 57 if t.AliasedType != nil { 58 return strings.Join(t.Modifiers, "") + t.AliasedType.FullName() 59 } 60 return strings.Join(t.Modifiers, "") + t.FullName() 61 } 62 63 func (t Type) FullSignature() string { 64 pkg := "" 65 if t.Package != "" { 66 pkg = t.Package + "." 67 } 68 69 return strings.Join(t.Modifiers, "") + pkg + t.GoType 70 } 71 72 func (t Type) IsPtr() bool { 73 return len(t.Modifiers) > 0 && t.Modifiers[0] == modPtr 74 } 75 76 func (t *Type) StripPtr() { 77 if !t.IsPtr() { 78 return 79 } 80 t.Modifiers = t.Modifiers[0 : len(t.Modifiers)-1] 81 } 82 83 func (t Type) IsSlice() bool { 84 return len(t.Modifiers) > 0 && t.Modifiers[0] == modList || 85 len(t.Modifiers) > 1 && t.Modifiers[0] == modPtr && t.Modifiers[1] == modList 86 } 87 88 func (t NamedType) IsMarshaled() bool { 89 return t.Marshaler != nil 90 } 91 92 func (t Type) Unmarshal(result, raw string) string { 93 return t.unmarshal(result, raw, t.Modifiers, 1) 94 } 95 96 func (t Type) unmarshal(result, raw string, remainingMods []string, depth int) string { 97 switch { 98 case len(remainingMods) > 0 && remainingMods[0] == modPtr: 99 ptr := "ptr" + strconv.Itoa(depth) 100 return tpl(`var {{.ptr}} {{.mods}}{{.t.FullName}} 101 if {{.raw}} != nil { 102 {{.next}} 103 {{.result}} = &{{.ptr -}} 104 } 105 `, map[string]interface{}{ 106 "ptr": ptr, 107 "t": t, 108 "raw": raw, 109 "result": result, 110 "mods": strings.Join(remainingMods[1:], ""), 111 "next": t.unmarshal(ptr, raw, remainingMods[1:], depth+1), 112 }) 113 114 case len(remainingMods) > 0 && remainingMods[0] == modList: 115 var rawIf = "rawIf" + strconv.Itoa(depth) 116 var index = "idx" + strconv.Itoa(depth) 117 118 return tpl(`var {{.rawSlice}} []interface{} 119 if {{.raw}} != nil { 120 if tmp1, ok := {{.raw}}.([]interface{}); ok { 121 {{.rawSlice}} = tmp1 122 } else { 123 {{.rawSlice}} = []interface{}{ {{.raw}} } 124 } 125 } 126 {{.result}} = make({{.type}}, len({{.rawSlice}})) 127 for {{.index}} := range {{.rawSlice}} { 128 {{ .next -}} 129 }`, map[string]interface{}{ 130 "raw": raw, 131 "rawSlice": rawIf, 132 "index": index, 133 "result": result, 134 "type": strings.Join(remainingMods, "") + t.NamedType.FullName(), 135 "next": t.unmarshal(result+"["+index+"]", rawIf+"["+index+"]", remainingMods[1:], depth+1), 136 }) 137 } 138 139 realResult := result 140 if t.AliasedType != nil { 141 result = "castTmp" 142 } 143 144 return tpl(`{{- if .t.AliasedType }} 145 var castTmp {{.t.FullName}} 146 {{ end }} 147 {{- if eq .t.GoType "map[string]interface{}" }} 148 {{- .result }} = {{.raw}}.(map[string]interface{}) 149 {{- else if .t.Marshaler }} 150 {{- .result }}, err = {{ .t.Marshaler.PkgDot }}Unmarshal{{.t.Marshaler.GoType}}({{.raw}}) 151 {{- else -}} 152 err = (&{{.result}}).UnmarshalGQL({{.raw}}) 153 {{- end }} 154 {{- if .t.AliasedType }} 155 {{ .realResult }} = {{.t.AliasedType.FullName}}(castTmp) 156 {{- end }}`, map[string]interface{}{ 157 "realResult": realResult, 158 "result": result, 159 "raw": raw, 160 "t": t, 161 }) 162 } 163 164 func (t Type) Marshal(val string) string { 165 if t.AliasedType != nil { 166 val = t.GoType + "(" + val + ")" 167 } 168 169 if t.Marshaler != nil { 170 return "return " + t.Marshaler.PkgDot() + "Marshal" + t.Marshaler.GoType + "(" + val + ")" 171 } 172 173 return "return " + val 174 }