diff --git a/codegen/type.go b/codegen/type.go index e28760b72fe..c16495e29ad 100644 --- a/codegen/type.go +++ b/codegen/type.go @@ -85,13 +85,14 @@ func (t Type) unmarshal(result, raw string, remainingMods []string, depth int) s switch { case len(remainingMods) > 0 && remainingMods[0] == modPtr: ptr := "ptr" + strconv.Itoa(depth) - return tpl(`var {{.ptr}} {{.t.FullName}} + return tpl(`var {{.ptr}} {{.mods}}{{.t.FullName}} {{.next}} {{.result}} = &{{.ptr -}} `, map[string]interface{}{ "ptr": ptr, "t": t, "result": result, + "mods": strings.Join(remainingMods[1:], ""), "next": t.unmarshal(ptr, raw, remainingMods[1:], depth+1), }) diff --git a/test/generated.go b/test/generated.go index 3f84a4ce6d3..65f1e182c8f 100644 --- a/test/generated.go +++ b/test/generated.go @@ -24,6 +24,7 @@ type Resolvers interface { Query_nestedInputs(ctx context.Context, input [][]OuterInput) (*bool, error) Query_nestedOutputs(ctx context.Context) ([][]OuterObject, error) Query_shapes(ctx context.Context) ([]Shape, error) + Query_recursive(ctx context.Context, input *RecursiveInputSlice) (*bool, error) } type executableSchema struct { @@ -183,6 +184,8 @@ func (ec *executionContext) _Query(sel []query.Selection) graphql.Marshaler { out.Values[i] = ec._Query_nestedOutputs(field) case "shapes": out.Values[i] = ec._Query_shapes(field) + case "recursive": + out.Values[i] = ec._Query_recursive(field) case "__schema": out.Values[i] = ec._Query___schema(field) case "__type": @@ -302,6 +305,39 @@ func (ec *executionContext) _Query_shapes(field graphql.CollectedField) graphql. }) } +func (ec *executionContext) _Query_recursive(field graphql.CollectedField) graphql.Marshaler { + var arg0 *RecursiveInputSlice + if tmp, ok := field.Args["input"]; ok { + var err error + var ptr1 RecursiveInputSlice + + ptr1, err = UnmarshalRecursiveInputSlice(tmp) + arg0 = &ptr1 + if err != nil { + ec.Error(err) + return graphql.Null + } + } + return graphql.Defer(func() (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + userErr := ec.recover(r) + ec.Error(userErr) + ret = graphql.Null + } + }() + res, err := ec.resolvers.Query_recursive(ec.ctx, arg0) + if err != nil { + ec.Error(err) + return graphql.Null + } + if res == nil { + return graphql.Null + } + return graphql.MarshalBoolean(*res) + }) +} + func (ec *executionContext) _Query___schema(field graphql.CollectedField) graphql.Marshaler { res := ec.introspectSchema() if res == nil { @@ -925,7 +961,33 @@ func UnmarshalOuterInput(v interface{}) (OuterInput, error) { return it, nil } -var parsedSchema = schema.MustParse("input InnerInput {\n id:Int!\n}\n\ninput OuterInput {\n inner: InnerInput!\n}\n\ntype OuterObject {\n inner: InnerObject!\n}\n\ntype InnerObject {\n id: Int!\n}\n\ninterface Shape {\n area: Float\n}\n\ntype Circle implements Shape {\n radius: Float\n area: Float\n}\n\ntype Rectangle implements Shape {\n length: Float\n width: Float\n area: Float\n}\n\nunion ShapeUnion = Circle | Rectangle\n\ntype Query {\n nestedInputs(input: [[OuterInput]] = [[{inner: {id: 1}}]]): Boolean\n nestedOutputs: [[OuterObject]]\n shapes: [Shape]\n}\n") +func UnmarshalRecursiveInputSlice(v interface{}) (RecursiveInputSlice, error) { + var it RecursiveInputSlice + + for k, v := range v.(map[string]interface{}) { + switch k { + case "self": + var err error + var ptr1 []*RecursiveInputSlice + rawIf2 := v.([]interface{}) + ptr1 = make([]*RecursiveInputSlice, len(rawIf2)) + for idx2 := range rawIf2 { + var ptr3 RecursiveInputSlice + + ptr3, err = UnmarshalRecursiveInputSlice(rawIf2[idx2]) + ptr1[idx2] = &ptr3 + } + it.Self = &ptr1 + if err != nil { + return it, err + } + } + } + + return it, nil +} + +var parsedSchema = schema.MustParse("input InnerInput {\n id:Int!\n}\n\ninput OuterInput {\n inner: InnerInput!\n}\n\ntype OuterObject {\n inner: InnerObject!\n}\n\ntype InnerObject {\n id: Int!\n}\n\ninterface Shape {\n area: Float\n}\n\ntype Circle implements Shape {\n radius: Float\n area: Float\n}\n\ntype Rectangle implements Shape {\n length: Float\n width: Float\n area: Float\n}\n\ninput RecursiveInputSlice {\n self: [RecursiveInputSlice!]\n}\n\nunion ShapeUnion = Circle | Rectangle\n\ntype Query {\n nestedInputs(input: [[OuterInput]] = [[{inner: {id: 1}}]]): Boolean\n nestedOutputs: [[OuterObject]]\n shapes: [Shape]\n recursive(input: RecursiveInputSlice): Boolean\n}\n") func (ec *executionContext) introspectSchema() *introspection.Schema { return introspection.WrapSchema(parsedSchema) diff --git a/test/models.go b/test/models.go index 56685be145b..d86daec9606 100644 --- a/test/models.go +++ b/test/models.go @@ -25,3 +25,7 @@ type Rectangle struct { func (r *Rectangle) Area() float64 { return r.Length * r.Width } + +type RecursiveInputSlice struct { + Self *[]*RecursiveInputSlice +} diff --git a/test/schema.graphql b/test/schema.graphql index 9ddf882b97d..3983c39f3e8 100644 --- a/test/schema.graphql +++ b/test/schema.graphql @@ -29,10 +29,15 @@ type Rectangle implements Shape { area: Float } +input RecursiveInputSlice { + self: [RecursiveInputSlice!] +} + union ShapeUnion = Circle | Rectangle type Query { nestedInputs(input: [[OuterInput]] = [[{inner: {id: 1}}]]): Boolean nestedOutputs: [[OuterObject]] shapes: [Shape] + recursive(input: RecursiveInputSlice): Boolean } diff --git a/test/types.json b/test/types.json index 474a4e7c778..2ee3d3baa11 100644 --- a/test/types.json +++ b/test/types.json @@ -2,5 +2,6 @@ "Shape": "github.com/vektah/gqlgen/test.Shape", "ShapeUnion": "github.com/vektah/gqlgen/test.ShapeUnion", "Circle": "github.com/vektah/gqlgen/test.Circle", - "Rectangle": "github.com/vektah/gqlgen/test.Rectangle" + "Rectangle": "github.com/vektah/gqlgen/test.Rectangle", + "RecursiveInputSlice": "github.com/vektah/gqlgen/test.RecursiveInputSlice" }