Skip to content

Commit

Permalink
Support map[string]interface{} in return types
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam Scarr committed Mar 12, 2019
1 parent 485ddf3 commit 0a92ca4
Show file tree
Hide file tree
Showing 14 changed files with 334 additions and 11 deletions.
7 changes: 7 additions & 0 deletions codegen/config/binder.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,13 @@ func (t *TypeReference) IsPtr() bool {
return isPtr
}

func (t *TypeReference) IsNilable() bool {
_, isPtr := t.GO.(*types.Pointer)
_, isMap := t.GO.(*types.Map)
_, isInterface := t.GO.(*types.Interface)
return isPtr || isMap || isInterface
}

func (t *TypeReference) IsSlice() bool {
_, isSlice := t.GO.(*types.Slice)
return isSlice
Expand Down
5 changes: 5 additions & 0 deletions codegen/field.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ func (b *builder) bindField(obj *Object, f *Field) error {
f.IsResolver = true
return nil
case obj.Type == config.MapType:
f.GoFieldType = GoFieldMap
return nil
case b.Config.Models[obj.Name].Fields[f.Name].FieldName != "":
f.GoFieldName = b.Config.Models[obj.Name].Fields[f.Name].FieldName
Expand Down Expand Up @@ -298,6 +299,10 @@ func (f *Field) IsVariable() bool {
return f.GoFieldType == GoFieldVariable
}

func (f *Field) IsMap() bool {
return f.GoFieldType == GoFieldMap
}

func (f *Field) IsConcurrent() bool {
if f.Object.DisableConcurrency {
return false
Expand Down
13 changes: 12 additions & 1 deletion codegen/field.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
}
}
{{ else }}
func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Context, field graphql.CollectedField{{ if not $object.Root }}, obj *{{$object.Type | ref}}{{end}}) graphql.Marshaler {
func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Context, field graphql.CollectedField{{ if not $object.Root }}, obj {{$object.Reference | ref}}{{end}}) graphql.Marshaler {
ctx = ec.Tracer.StartFieldExecution(ctx, field)
defer func () { ec.Tracer.EndFieldExecution(ctx) }()
rctx := &graphql.ResolverContext{
Expand All @@ -60,6 +60,17 @@
ctx = rctx // use context from middleware stack in children
{{- if $field.IsResolver }}
return ec.resolvers.{{ $field.ShortInvocation }}
{{- else if $field.IsMap }}
switch v := {{$field.GoReceiverName}}[{{$field.Name|quote}}].(type) {
case {{$field.TypeReference.GO | ref}}:
return v, nil
case {{$field.TypeReference.Elem.GO | ref}}:
return &v, nil
case nil:
return ({{$field.TypeReference.GO | ref}})(nil), nil
default:
return nil, fmt.Errorf("unexpected type %T for field %s", v, {{ $field.Name | quote}})
}
{{- else if $field.IsMethod }}
{{- if $field.NoErr }}
return {{$field.GoReceiverName}}.{{$field.GoFieldName}}({{ $field.CallArgs }}), nil
Expand Down
10 changes: 10 additions & 0 deletions codegen/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const (
GoFieldUndefined GoFieldType = iota
GoFieldMethod
GoFieldVariable
GoFieldMap
)

type Object struct {
Expand Down Expand Up @@ -80,6 +81,15 @@ func (b *builder) buildObject(typ *ast.Definition) (*Object, error) {
return obj, nil
}

func (o *Object) Reference() types.Type {
switch o.Type.(type) {
case *types.Pointer, *types.Slice, *types.Map:
return o.Type
}

return types.NewPointer(o.Type)
}

type Objects []*Object

func (o *Object) Implementors() string {
Expand Down
2 changes: 1 addition & 1 deletion codegen/object.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.Selec
}
}
{{- else }}
func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet{{ if not $object.Root }},obj *{{$object.Type | ref }}{{ end }}) graphql.Marshaler {
func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet{{ if not $object.Root }},obj {{$object.Reference | ref }}{{ end }}) graphql.Marshaler {
fields := graphql.CollectFields(ctx, sel, {{$object.Name|lcFirst}}Implementors)
{{if $object.Root}}
ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
Expand Down
6 changes: 0 additions & 6 deletions codegen/testdata/schema.graphql
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
type Query {
invalidIdentifier: InvalidIdentifier
collision: It
mapInput(input: Changes): Boolean
recursive(input: RecursiveInputSlice): Boolean
nestedInputs(input: [[OuterInput]] = [[{inner: {id: 1}}]]): Boolean
nestedOutputs: [[OuterObject]]
Expand Down Expand Up @@ -49,11 +48,6 @@ type It {
id: ID!
}

input Changes {
a: Int
b: Int
}

input RecursiveInputSlice {
self: [RecursiveInputSlice!]
}
Expand Down
Loading

0 comments on commit 0a92ca4

Please sign in to comment.