From 3900a41db7a9afaade738ddcfe20b7463013ae6a Mon Sep 17 00:00:00 2001 From: Adam Scarr Date: Sun, 11 Feb 2018 19:03:44 +1100 Subject: [PATCH] tidy up json writing --- example/dataloader/generated.go | 996 ++++++++------------- example/starwars/generated.go | 1426 +++++++++++-------------------- example/starwars/starwars.go | 2 + example/todo/generated.go | 907 +++++++------------- example/todo/todo_test.go | 14 + jsonw/jsonw.go | 115 +++ jsonw/jsonw_test.go | 38 + jsonw/output.go | 126 --- jsonw/output_test.go | 45 - neelance/errors/errors.go | 38 +- templates/file.gotpl | 18 +- templates/interface.gotpl | 6 +- templates/object.gotpl | 59 +- types.go | 64 +- 14 files changed, 1408 insertions(+), 2446 deletions(-) create mode 100644 jsonw/jsonw.go create mode 100644 jsonw/jsonw_test.go delete mode 100644 jsonw/output.go delete mode 100644 jsonw/output_test.go diff --git a/example/dataloader/generated.go b/example/dataloader/generated.go index 7e15e478e7c..aa6bc1c345b 100644 --- a/example/dataloader/generated.go +++ b/example/dataloader/generated.go @@ -53,27 +53,23 @@ func NewExecutor(resolvers Resolvers) func(context.Context, string, string, map[ ctx: ctx, } - var result jsonw.JsonWriter + var data jsonw.Writer if op.Type == query.Query { - result = c._query(op.Selections, nil) + data = c._query(op.Selections, nil) } else { return []*errors.QueryError{errors.Errorf("unsupported operation type")} } c.wg.Wait() - writer := jsonw.New(w) - writer.BeginObject() - - writer.ObjectKey("data") - result.WriteJson(writer) + result := &jsonw.OrderedMap{} + result.Add("data", data) if len(c.Errors) > 0 { - writer.ObjectKey("errors") - errors.WriteErrors(w, c.Errors) + result.Add("errors", errors.ErrorWriter(c.Errors)) } - writer.EndObject() + result.WriteJson(w) return nil } } @@ -87,296 +83,206 @@ type executionContext struct { wg sync.WaitGroup } -type _AddressNode struct { - _fields []collectedField - Id int - Street string - Country string -} - var addressImplementors = []string{"Address"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _address(sel []query.Selection, it *Address) jsonw.JsonWriter { - node := _AddressNode{ - _fields: ec.collectFields(sel, addressImplementors, map[string]bool{}), - } +func (ec *executionContext) _address(sel []query.Selection, it *Address) jsonw.Writer { + fields := ec.collectFields(sel, addressImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "id": res := it.ID - node.Id = res + + out.Values[i] = jsonw.Int(res) case "street": res := it.Street - node.Street = res + + out.Values[i] = jsonw.String(res) case "country": res := it.Country - node.Country = res + + out.Values[i] = jsonw.String(res) default: panic("unknown field " + strconv.Quote(field.Name)) } } - return &node -} - -func (t *_AddressNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "id": - w.ObjectKey("id") - w.Int(t.Id) - case "street": - w.ObjectKey("street") - w.String(t.Street) - case "country": - w.ObjectKey("country") - w.String(t.Country) - } - } - w.EndObject() -} - -type _CustomerNode struct { - _fields []collectedField - Id int - Name string - Address jsonw.JsonWriter - Orders []jsonw.JsonWriter + return out } var customerImplementors = []string{"Customer"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _customer(sel []query.Selection, it *Customer) jsonw.JsonWriter { - node := _CustomerNode{ - _fields: ec.collectFields(sel, customerImplementors, map[string]bool{}), - } +func (ec *executionContext) _customer(sel []query.Selection, it *Customer) jsonw.Writer { + fields := ec.collectFields(sel, customerImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "id": res := it.ID - node.Id = res + + out.Values[i] = jsonw.Int(res) case "name": res := it.Name - node.Name = res + + out.Values[i] = jsonw.String(res) case "address": ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.Customer_address(ec.ctx, it) if err != nil { ec.Error(err) return } - if res != nil { - node.Address = ec._address(field.Selections, res) + + if res == nil { + out.Values[i] = jsonw.Null + } else { + out.Values[i] = ec._address(field.Selections, res) } - }(field) + }(i, field) case "orders": ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.Customer_orders(ec.ctx, it) if err != nil { ec.Error(err) return } - if res != nil { - for i := range res { - node.Orders = append(node.Orders, ec._order(field.Selections, &res[i])) - } + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + tmp1 = ec._order(field.Selections, &loopval1) + arr1 = append(arr1, tmp1) } - }(field) + out.Values[i] = arr1 + }(i, field) default: panic("unknown field " + strconv.Quote(field.Name)) } } - return &node -} - -func (t *_CustomerNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "id": - w.ObjectKey("id") - w.Int(t.Id) - case "name": - w.ObjectKey("name") - w.String(t.Name) - case "address": - w.ObjectKey("address") - if t.Address == nil { - w.Null() - } else { - t.Address.WriteJson(w) - } - case "orders": - w.ObjectKey("orders") - w.BeginArray() - for _, val := range t.Orders { - val.WriteJson(w) - } - w.EndArray() - } - } - w.EndObject() -} - -type _ItemNode struct { - _fields []collectedField - Name string + return out } var itemImplementors = []string{"Item"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _item(sel []query.Selection, it *Item) jsonw.JsonWriter { - node := _ItemNode{ - _fields: ec.collectFields(sel, itemImplementors, map[string]bool{}), - } +func (ec *executionContext) _item(sel []query.Selection, it *Item) jsonw.Writer { + fields := ec.collectFields(sel, itemImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "name": res := it.Name - node.Name = res + + out.Values[i] = jsonw.String(res) default: panic("unknown field " + strconv.Quote(field.Name)) } } - return &node -} - -func (t *_ItemNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "name": - w.ObjectKey("name") - w.String(t.Name) - } - } - w.EndObject() -} - -type _OrderNode struct { - _fields []collectedField - Id int - Date time.Time - Amount float64 - Items []jsonw.JsonWriter + return out } var orderImplementors = []string{"Order"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _order(sel []query.Selection, it *Order) jsonw.JsonWriter { - node := _OrderNode{ - _fields: ec.collectFields(sel, orderImplementors, map[string]bool{}), - } +func (ec *executionContext) _order(sel []query.Selection, it *Order) jsonw.Writer { + fields := ec.collectFields(sel, orderImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "id": res := it.ID - node.Id = res + + out.Values[i] = jsonw.Int(res) case "date": res := it.Date - node.Date = res + + out.Values[i] = jsonw.Time(res) case "amount": res := it.Amount - node.Amount = res + + out.Values[i] = jsonw.Float64(res) case "items": ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.Order_items(ec.ctx, it) if err != nil { ec.Error(err) return } - if res != nil { - for i := range res { - node.Items = append(node.Items, ec._item(field.Selections, &res[i])) - } + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + tmp1 = ec._item(field.Selections, &loopval1) + arr1 = append(arr1, tmp1) } - }(field) + out.Values[i] = arr1 + }(i, field) default: panic("unknown field " + strconv.Quote(field.Name)) } } - return &node -} - -func (t *_OrderNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "id": - w.ObjectKey("id") - w.Int(t.Id) - case "date": - w.ObjectKey("date") - w.Time(t.Date) - case "amount": - w.ObjectKey("amount") - w.Float64(t.Amount) - case "items": - w.ObjectKey("items") - w.BeginArray() - for _, val := range t.Items { - val.WriteJson(w) - } - w.EndArray() - } - } - w.EndObject() -} - -type _QueryNode struct { - _fields []collectedField - Customers []jsonw.JsonWriter - __schema jsonw.JsonWriter - __type jsonw.JsonWriter + return out } var queryImplementors = []string{"Query"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _query(sel []query.Selection, it *interface{}) jsonw.JsonWriter { - node := _QueryNode{ - _fields: ec.collectFields(sel, queryImplementors, map[string]bool{}), - } +func (ec *executionContext) _query(sel []query.Selection, it *interface{}) jsonw.Writer { + fields := ec.collectFields(sel, queryImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "customers": ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.Query_customers(ec.ctx) if err != nil { ec.Error(err) return } - if res != nil { - for i := range res { - node.Customers = append(node.Customers, ec._customer(field.Selections, &res[i])) - } + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + tmp1 = ec._customer(field.Selections, &loopval1) + arr1 = append(arr1, tmp1) } - }(field) + out.Values[i] = arr1 + }(i, field) case "__schema": res := ec.introspectSchema() - if res != nil { - node.__schema = ec.___Schema(field.Selections, res) + + if res == nil { + out.Values[i] = jsonw.Null + } else { + out.Values[i] = ec.___Schema(field.Selections, res) } case "__type": var arg0 string @@ -389,505 +295,336 @@ func (ec *executionContext) _query(sel []query.Selection, it *interface{}) jsonw arg0 = tmp2 } res := ec.introspectType(arg0) - if res != nil { - node.__type = ec.___Type(field.Selections, res) - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - return &node -} - -func (t *_QueryNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "customers": - w.ObjectKey("customers") - w.BeginArray() - for _, val := range t.Customers { - val.WriteJson(w) - } - w.EndArray() - case "__schema": - w.ObjectKey("__schema") - if t.__schema == nil { - w.Null() + if res == nil { + out.Values[i] = jsonw.Null } else { - t.__schema.WriteJson(w) - } - case "__type": - w.ObjectKey("__type") - if t.__type == nil { - w.Null() - } else { - t.__type.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type ___DirectiveNode struct { - _fields []collectedField - Name string - Description *string - Locations []string - Args []jsonw.JsonWriter + return out } var __DirectiveImplementors = []string{"__Directive"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___Directive(sel []query.Selection, it *introspection.Directive) jsonw.JsonWriter { - node := ___DirectiveNode{ - _fields: ec.collectFields(sel, __DirectiveImplementors, map[string]bool{}), - } +func (ec *executionContext) ___Directive(sel []query.Selection, it *introspection.Directive) jsonw.Writer { + fields := ec.collectFields(sel, __DirectiveImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "name": res := it.Name() - node.Name = res + + out.Values[i] = jsonw.String(res) case "description": res := it.Description() - node.Description = res - case "locations": - res := it.Locations() - node.Locations = res - case "args": - res := it.Args() - if res != nil { - for i := range res { - node.Args = append(node.Args, ec.___InputValue(field.Selections, res[i])) - } - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - - return &node -} -func (t *___DirectiveNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "name": - w.ObjectKey("name") - w.String(t.Name) - case "description": - w.ObjectKey("description") - if t.Description == nil { - w.Null() + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.Description) + out.Values[i] = jsonw.String(*res) } case "locations": - w.ObjectKey("locations") - w.BeginArray() - for _, val := range t.Locations { - w.String(val) + res := it.Locations() + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + tmp1 = jsonw.String(loopval1) + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 case "args": - w.ObjectKey("args") - w.BeginArray() - for _, val := range t.Args { - if val == nil { - w.Null() + res := it.Args() + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___InputValue(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type ___EnumValueNode struct { - _fields []collectedField - Name string - Description *string - IsDeprecated bool - DeprecationReason *string + return out } var __EnumValueImplementors = []string{"__EnumValue"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___EnumValue(sel []query.Selection, it *introspection.EnumValue) jsonw.JsonWriter { - node := ___EnumValueNode{ - _fields: ec.collectFields(sel, __EnumValueImplementors, map[string]bool{}), - } +func (ec *executionContext) ___EnumValue(sel []query.Selection, it *introspection.EnumValue) jsonw.Writer { + fields := ec.collectFields(sel, __EnumValueImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "name": res := it.Name() - node.Name = res + + out.Values[i] = jsonw.String(res) case "description": res := it.Description() - node.Description = res - case "isDeprecated": - res := it.IsDeprecated() - node.IsDeprecated = res - case "deprecationReason": - res := it.DeprecationReason() - node.DeprecationReason = res - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - - return &node -} -func (t *___EnumValueNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "name": - w.ObjectKey("name") - w.String(t.Name) - case "description": - w.ObjectKey("description") - if t.Description == nil { - w.Null() + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.Description) + out.Values[i] = jsonw.String(*res) } case "isDeprecated": - w.ObjectKey("isDeprecated") - w.Bool(t.IsDeprecated) + res := it.IsDeprecated() + + out.Values[i] = jsonw.Bool(res) case "deprecationReason": - w.ObjectKey("deprecationReason") - if t.DeprecationReason == nil { - w.Null() + res := it.DeprecationReason() + + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.DeprecationReason) + out.Values[i] = jsonw.String(*res) } + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type ___FieldNode struct { - _fields []collectedField - Name string - Description *string - Args []jsonw.JsonWriter - Type jsonw.JsonWriter - IsDeprecated bool - DeprecationReason *string + return out } var __FieldImplementors = []string{"__Field"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___Field(sel []query.Selection, it *introspection.Field) jsonw.JsonWriter { - node := ___FieldNode{ - _fields: ec.collectFields(sel, __FieldImplementors, map[string]bool{}), - } +func (ec *executionContext) ___Field(sel []query.Selection, it *introspection.Field) jsonw.Writer { + fields := ec.collectFields(sel, __FieldImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "name": res := it.Name() - node.Name = res + + out.Values[i] = jsonw.String(res) case "description": res := it.Description() - node.Description = res - case "args": - res := it.Args() - if res != nil { - for i := range res { - node.Args = append(node.Args, ec.___InputValue(field.Selections, res[i])) - } - } - case "type": - res := it.Type() - if res != nil { - node.Type = ec.___Type(field.Selections, res) - } - case "isDeprecated": - res := it.IsDeprecated() - node.IsDeprecated = res - case "deprecationReason": - res := it.DeprecationReason() - node.DeprecationReason = res - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - - return &node -} -func (t *___FieldNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "name": - w.ObjectKey("name") - w.String(t.Name) - case "description": - w.ObjectKey("description") - if t.Description == nil { - w.Null() + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.Description) + out.Values[i] = jsonw.String(*res) } case "args": - w.ObjectKey("args") - w.BeginArray() - for _, val := range t.Args { - if val == nil { - w.Null() + res := it.Args() + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___InputValue(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 case "type": - w.ObjectKey("type") - if t.Type == nil { - w.Null() + res := it.Type() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.Type.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } case "isDeprecated": - w.ObjectKey("isDeprecated") - w.Bool(t.IsDeprecated) + res := it.IsDeprecated() + + out.Values[i] = jsonw.Bool(res) case "deprecationReason": - w.ObjectKey("deprecationReason") - if t.DeprecationReason == nil { - w.Null() + res := it.DeprecationReason() + + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.DeprecationReason) + out.Values[i] = jsonw.String(*res) } + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type ___InputValueNode struct { - _fields []collectedField - Name string - Description *string - Type jsonw.JsonWriter - DefaultValue *string + return out } var __InputValueImplementors = []string{"__InputValue"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___InputValue(sel []query.Selection, it *introspection.InputValue) jsonw.JsonWriter { - node := ___InputValueNode{ - _fields: ec.collectFields(sel, __InputValueImplementors, map[string]bool{}), - } +func (ec *executionContext) ___InputValue(sel []query.Selection, it *introspection.InputValue) jsonw.Writer { + fields := ec.collectFields(sel, __InputValueImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "name": res := it.Name() - node.Name = res + + out.Values[i] = jsonw.String(res) case "description": res := it.Description() - node.Description = res - case "type": - res := it.Type() - if res != nil { - node.Type = ec.___Type(field.Selections, res) - } - case "defaultValue": - res := it.DefaultValue() - node.DefaultValue = res - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - return &node -} - -func (t *___InputValueNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "name": - w.ObjectKey("name") - w.String(t.Name) - case "description": - w.ObjectKey("description") - if t.Description == nil { - w.Null() + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.Description) + out.Values[i] = jsonw.String(*res) } case "type": - w.ObjectKey("type") - if t.Type == nil { - w.Null() + res := it.Type() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.Type.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } case "defaultValue": - w.ObjectKey("defaultValue") - if t.DefaultValue == nil { - w.Null() + res := it.DefaultValue() + + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.DefaultValue) + out.Values[i] = jsonw.String(*res) } + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type ___SchemaNode struct { - _fields []collectedField - Types []jsonw.JsonWriter - QueryType jsonw.JsonWriter - MutationType jsonw.JsonWriter - SubscriptionType jsonw.JsonWriter - Directives []jsonw.JsonWriter + return out } var __SchemaImplementors = []string{"__Schema"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___Schema(sel []query.Selection, it *introspection.Schema) jsonw.JsonWriter { - node := ___SchemaNode{ - _fields: ec.collectFields(sel, __SchemaImplementors, map[string]bool{}), - } +func (ec *executionContext) ___Schema(sel []query.Selection, it *introspection.Schema) jsonw.Writer { + fields := ec.collectFields(sel, __SchemaImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "types": res := it.Types() - if res != nil { - for i := range res { - node.Types = append(node.Types, ec.___Type(field.Selections, res[i])) - } - } - case "queryType": - res := it.QueryType() - if res != nil { - node.QueryType = ec.___Type(field.Selections, res) - } - case "mutationType": - res := it.MutationType() - if res != nil { - node.MutationType = ec.___Type(field.Selections, res) - } - case "subscriptionType": - res := it.SubscriptionType() - if res != nil { - node.SubscriptionType = ec.___Type(field.Selections, res) - } - case "directives": - res := it.Directives() - if res != nil { - for i := range res { - node.Directives = append(node.Directives, ec.___Directive(field.Selections, res[i])) - } - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - return &node -} + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer -func (t *___SchemaNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "types": - w.ObjectKey("types") - w.BeginArray() - for _, val := range t.Types { - if val == nil { - w.Null() + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___Type(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 case "queryType": - w.ObjectKey("queryType") - if t.QueryType == nil { - w.Null() + res := it.QueryType() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.QueryType.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } case "mutationType": - w.ObjectKey("mutationType") - if t.MutationType == nil { - w.Null() + res := it.MutationType() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.MutationType.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } case "subscriptionType": - w.ObjectKey("subscriptionType") - if t.SubscriptionType == nil { - w.Null() + res := it.SubscriptionType() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.SubscriptionType.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } case "directives": - w.ObjectKey("directives") - w.BeginArray() - for _, val := range t.Directives { - if val == nil { - w.Null() + res := it.Directives() + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___Directive(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type ___TypeNode struct { - _fields []collectedField - Kind string - Name *string - Description *string - Fields []jsonw.JsonWriter - Interfaces []jsonw.JsonWriter - PossibleTypes []jsonw.JsonWriter - EnumValues []jsonw.JsonWriter - InputFields []jsonw.JsonWriter - OfType jsonw.JsonWriter + return out } var __TypeImplementors = []string{"__Type"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___Type(sel []query.Selection, it *introspection.Type) jsonw.JsonWriter { - node := ___TypeNode{ - _fields: ec.collectFields(sel, __TypeImplementors, map[string]bool{}), - } +func (ec *executionContext) ___Type(sel []query.Selection, it *introspection.Type) jsonw.Writer { + fields := ec.collectFields(sel, __TypeImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "kind": res := it.Kind() - node.Kind = res + + out.Values[i] = jsonw.String(res) case "name": res := it.Name() - node.Name = res + + if res == nil { + out.Values[i] = jsonw.Null + } else { + out.Values[i] = jsonw.String(*res) + } case "description": res := it.Description() - node.Description = res + + if res == nil { + out.Values[i] = jsonw.Null + } else { + out.Values[i] = jsonw.String(*res) + } case "fields": var arg0 bool if tmp, ok := field.Args["includeDeprecated"]; ok { @@ -899,25 +636,49 @@ func (ec *executionContext) ___Type(sel []query.Selection, it *introspection.Typ arg0 = tmp2 } res := it.Fields(arg0) - if res != nil { - for i := range res { - node.Fields = append(node.Fields, ec.___Field(field.Selections, res[i])) + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null + } else { + tmp1 = ec.___Field(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } + out.Values[i] = arr1 case "interfaces": res := it.Interfaces() - if res != nil { - for i := range res { - node.Interfaces = append(node.Interfaces, ec.___Type(field.Selections, res[i])) + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null + } else { + tmp1 = ec.___Type(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } + out.Values[i] = arr1 case "possibleTypes": res := it.PossibleTypes() - if res != nil { - for i := range res { - node.PossibleTypes = append(node.PossibleTypes, ec.___Type(field.Selections, res[i])) + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null + } else { + tmp1 = ec.___Type(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } + out.Values[i] = arr1 case "enumValues": var arg0 bool if tmp, ok := field.Args["includeDeprecated"]; ok { @@ -929,117 +690,48 @@ func (ec *executionContext) ___Type(sel []query.Selection, it *introspection.Typ arg0 = tmp2 } res := it.EnumValues(arg0) - if res != nil { - for i := range res { - node.EnumValues = append(node.EnumValues, ec.___EnumValue(field.Selections, res[i])) - } - } - case "inputFields": - res := it.InputFields() - if res != nil { - for i := range res { - node.InputFields = append(node.InputFields, ec.___InputValue(field.Selections, res[i])) - } - } - case "ofType": - res := it.OfType() - if res != nil { - node.OfType = ec.___Type(field.Selections, res) - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - return &node -} + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer -func (t *___TypeNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "kind": - w.ObjectKey("kind") - w.String(t.Kind) - case "name": - w.ObjectKey("name") - if t.Name == nil { - w.Null() - } else { - w.String(*t.Name) - } - case "description": - w.ObjectKey("description") - if t.Description == nil { - w.Null() - } else { - w.String(*t.Description) - } - case "fields": - w.ObjectKey("fields") - w.BeginArray() - for _, val := range t.Fields { - if val == nil { - w.Null() + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___EnumValue(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() - case "interfaces": - w.ObjectKey("interfaces") - w.BeginArray() - for _, val := range t.Interfaces { - if val == nil { - w.Null() - } else { - val.WriteJson(w) - } - } - w.EndArray() - case "possibleTypes": - w.ObjectKey("possibleTypes") - w.BeginArray() - for _, val := range t.PossibleTypes { - if val == nil { - w.Null() - } else { - val.WriteJson(w) - } - } - w.EndArray() - case "enumValues": - w.ObjectKey("enumValues") - w.BeginArray() - for _, val := range t.EnumValues { - if val == nil { - w.Null() - } else { - val.WriteJson(w) - } - } - w.EndArray() + out.Values[i] = arr1 case "inputFields": - w.ObjectKey("inputFields") - w.BeginArray() - for _, val := range t.InputFields { - if val == nil { - w.Null() + res := it.InputFields() + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___InputValue(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 case "ofType": - w.ObjectKey("ofType") - if t.OfType == nil { - w.Null() + res := it.OfType() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.OfType.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() + + return out } var parsedSchema = schema.MustParse("schema {\n query: Query\n}\n\ntype Query {\n customers: [Customer!]\n}\n\ntype Customer {\n id: Int!\n name: String!\n address: Address\n orders: [Order!]\n}\n\ntype Address {\n id: Int!\n street: String\n country: String\n}\n\ntype Order {\n id: Int!\n date: Time\n amount: Float!\n items: [Item!]\n}\n\ntype Item {\n name: String\n}\n") diff --git a/example/starwars/generated.go b/example/starwars/generated.go index bef3123d020..aed19d90e60 100644 --- a/example/starwars/generated.go +++ b/example/starwars/generated.go @@ -67,29 +67,25 @@ func NewExecutor(resolvers Resolvers) func(context.Context, string, string, map[ ctx: ctx, } - var result jsonw.JsonWriter + var data jsonw.Writer if op.Type == query.Query { - result = c._query(op.Selections, nil) + data = c._query(op.Selections, nil) } else if op.Type == query.Mutation { - result = c._mutation(op.Selections, nil) + data = c._mutation(op.Selections, nil) } else { return []*errors.QueryError{errors.Errorf("unsupported operation type")} } c.wg.Wait() - writer := jsonw.New(w) - writer.BeginObject() - - writer.ObjectKey("data") - result.WriteJson(writer) + result := &jsonw.OrderedMap{} + result.Add("data", data) if len(c.Errors) > 0 { - writer.ObjectKey("errors") - errors.WriteErrors(w, c.Errors) + result.Add("errors", errors.ErrorWriter(c.Errors)) } - writer.EndObject() + result.WriteJson(w) return nil } } @@ -103,47 +99,43 @@ type executionContext struct { wg sync.WaitGroup } -type _DroidNode struct { - _fields []collectedField - Id string - Name string - Friends []jsonw.JsonWriter - FriendsConnection jsonw.JsonWriter - AppearsIn []string - PrimaryFunction string -} - var droidImplementors = []string{"Droid", "Character"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _droid(sel []query.Selection, it *Droid) jsonw.JsonWriter { - node := _DroidNode{ - _fields: ec.collectFields(sel, droidImplementors, map[string]bool{}), - } +func (ec *executionContext) _droid(sel []query.Selection, it *Droid) jsonw.Writer { + fields := ec.collectFields(sel, droidImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "id": res := it.ID - node.Id = res + + out.Values[i] = jsonw.String(res) case "name": res := it.Name - node.Name = res + + out.Values[i] = jsonw.String(res) case "friends": ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.Droid_friends(ec.ctx, it) if err != nil { ec.Error(err) return } - if res != nil { - for i := range res { - node.Friends = append(node.Friends, ec._character(field.Selections, res[i])) - } + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + tmp1 = ec._character(field.Selections, &loopval1) + arr1 = append(arr1, tmp1) } - }(field) + out.Values[i] = arr1 + }(i, field) case "friendsConnection": var arg0 *int if tmp, ok := field.Args["first"]; ok { @@ -164,228 +156,147 @@ func (ec *executionContext) _droid(sel []query.Selection, it *Droid) jsonw.JsonW arg1 = &tmp2 } ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.Droid_friendsConnection(ec.ctx, it, arg0, arg1) if err != nil { ec.Error(err) return } - node.FriendsConnection = ec._friendsConnection(field.Selections, &res) - }(field) + + out.Values[i] = ec._friendsConnection(field.Selections, &res) + }(i, field) case "appearsIn": res := it.AppearsIn - node.AppearsIn = res + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + tmp1 = jsonw.String(loopval1) + arr1 = append(arr1, tmp1) + } + out.Values[i] = arr1 case "primaryFunction": res := it.PrimaryFunction - node.PrimaryFunction = res + + out.Values[i] = jsonw.String(res) default: panic("unknown field " + strconv.Quote(field.Name)) } } - return &node -} - -func (t *_DroidNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "id": - w.ObjectKey("id") - w.String(t.Id) - case "name": - w.ObjectKey("name") - w.String(t.Name) - case "friends": - w.ObjectKey("friends") - w.BeginArray() - for _, val := range t.Friends { - val.WriteJson(w) - } - w.EndArray() - case "friendsConnection": - w.ObjectKey("friendsConnection") - t.FriendsConnection.WriteJson(w) - case "appearsIn": - w.ObjectKey("appearsIn") - w.BeginArray() - for _, val := range t.AppearsIn { - w.String(val) - } - w.EndArray() - case "primaryFunction": - w.ObjectKey("primaryFunction") - w.String(t.PrimaryFunction) - } - } - w.EndObject() -} - -type _FriendsConnectionNode struct { - _fields []collectedField - TotalCount int - Edges []jsonw.JsonWriter - Friends []jsonw.JsonWriter - PageInfo jsonw.JsonWriter + return out } var friendsConnectionImplementors = []string{"FriendsConnection"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _friendsConnection(sel []query.Selection, it *FriendsConnection) jsonw.JsonWriter { - node := _FriendsConnectionNode{ - _fields: ec.collectFields(sel, friendsConnectionImplementors, map[string]bool{}), - } +func (ec *executionContext) _friendsConnection(sel []query.Selection, it *FriendsConnection) jsonw.Writer { + fields := ec.collectFields(sel, friendsConnectionImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "totalCount": res := it.TotalCount() - node.TotalCount = res + + out.Values[i] = jsonw.Int(res) case "edges": ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.FriendsConnection_edges(ec.ctx, it) if err != nil { ec.Error(err) return } - if res != nil { - for i := range res { - node.Edges = append(node.Edges, ec._friendsEdge(field.Selections, &res[i])) - } + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + tmp1 = ec._friendsEdge(field.Selections, &loopval1) + arr1 = append(arr1, tmp1) } - }(field) + out.Values[i] = arr1 + }(i, field) case "friends": ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.FriendsConnection_friends(ec.ctx, it) if err != nil { ec.Error(err) return } - if res != nil { - for i := range res { - node.Friends = append(node.Friends, ec._character(field.Selections, res[i])) - } + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + tmp1 = ec._character(field.Selections, &loopval1) + arr1 = append(arr1, tmp1) } - }(field) + out.Values[i] = arr1 + }(i, field) case "pageInfo": res := it.PageInfo() - node.PageInfo = ec._pageInfo(field.Selections, &res) + + out.Values[i] = ec._pageInfo(field.Selections, &res) default: panic("unknown field " + strconv.Quote(field.Name)) } } - return &node -} - -func (t *_FriendsConnectionNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "totalCount": - w.ObjectKey("totalCount") - w.Int(t.TotalCount) - case "edges": - w.ObjectKey("edges") - w.BeginArray() - for _, val := range t.Edges { - val.WriteJson(w) - } - w.EndArray() - case "friends": - w.ObjectKey("friends") - w.BeginArray() - for _, val := range t.Friends { - val.WriteJson(w) - } - w.EndArray() - case "pageInfo": - w.ObjectKey("pageInfo") - t.PageInfo.WriteJson(w) - } - } - w.EndObject() -} - -type _FriendsEdgeNode struct { - _fields []collectedField - Cursor string - Node jsonw.JsonWriter + return out } var friendsEdgeImplementors = []string{"FriendsEdge"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _friendsEdge(sel []query.Selection, it *FriendsEdge) jsonw.JsonWriter { - node := _FriendsEdgeNode{ - _fields: ec.collectFields(sel, friendsEdgeImplementors, map[string]bool{}), - } +func (ec *executionContext) _friendsEdge(sel []query.Selection, it *FriendsEdge) jsonw.Writer { + fields := ec.collectFields(sel, friendsEdgeImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "cursor": res := it.Cursor - node.Cursor = res + + out.Values[i] = jsonw.String(res) case "node": res := it.Node - node.Node = ec._character(field.Selections, res) + + out.Values[i] = ec._character(field.Selections, &res) default: panic("unknown field " + strconv.Quote(field.Name)) } } - return &node -} - -func (t *_FriendsEdgeNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "cursor": - w.ObjectKey("cursor") - w.String(t.Cursor) - case "node": - w.ObjectKey("node") - t.Node.WriteJson(w) - } - } - w.EndObject() -} - -type _HumanNode struct { - _fields []collectedField - Id string - Name string - Height float64 - Mass float64 - Friends []jsonw.JsonWriter - FriendsConnection jsonw.JsonWriter - AppearsIn []string - Starships []jsonw.JsonWriter + return out } var humanImplementors = []string{"Human", "Character"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _human(sel []query.Selection, it *Human) jsonw.JsonWriter { - node := _HumanNode{ - _fields: ec.collectFields(sel, humanImplementors, map[string]bool{}), - } +func (ec *executionContext) _human(sel []query.Selection, it *Human) jsonw.Writer { + fields := ec.collectFields(sel, humanImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "id": res := it.ID - node.Id = res + + out.Values[i] = jsonw.String(res) case "name": res := it.Name - node.Name = res + + out.Values[i] = jsonw.String(res) case "height": var arg0 string if tmp, ok := field.Args["unit"]; ok { @@ -397,25 +308,30 @@ func (ec *executionContext) _human(sel []query.Selection, it *Human) jsonw.JsonW arg0 = tmp2 } res := it.Height(arg0) - node.Height = res + + out.Values[i] = jsonw.Float64(res) case "mass": res := it.Mass - node.Mass = res + + out.Values[i] = jsonw.Float64(res) case "friends": ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.Human_friends(ec.ctx, it) if err != nil { ec.Error(err) return } - if res != nil { - for i := range res { - node.Friends = append(node.Friends, ec._character(field.Selections, res[i])) - } + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + tmp1 = ec._character(field.Selections, &loopval1) + arr1 = append(arr1, tmp1) } - }(field) + out.Values[i] = arr1 + }(i, field) case "friendsConnection": var arg0 *int if tmp, ok := field.Args["first"]; ok { @@ -436,100 +352,62 @@ func (ec *executionContext) _human(sel []query.Selection, it *Human) jsonw.JsonW arg1 = &tmp2 } ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.Human_friendsConnection(ec.ctx, it, arg0, arg1) if err != nil { ec.Error(err) return } - node.FriendsConnection = ec._friendsConnection(field.Selections, &res) - }(field) + + out.Values[i] = ec._friendsConnection(field.Selections, &res) + }(i, field) case "appearsIn": res := it.AppearsIn - node.AppearsIn = res + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + tmp1 = jsonw.String(loopval1) + arr1 = append(arr1, tmp1) + } + out.Values[i] = arr1 case "starships": ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.Human_starships(ec.ctx, it) if err != nil { ec.Error(err) return } - if res != nil { - for i := range res { - node.Starships = append(node.Starships, ec._starship(field.Selections, &res[i])) - } + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + tmp1 = ec._starship(field.Selections, &loopval1) + arr1 = append(arr1, tmp1) } - }(field) + out.Values[i] = arr1 + }(i, field) default: panic("unknown field " + strconv.Quote(field.Name)) } } - return &node -} - -func (t *_HumanNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "id": - w.ObjectKey("id") - w.String(t.Id) - case "name": - w.ObjectKey("name") - w.String(t.Name) - case "height": - w.ObjectKey("height") - w.Float64(t.Height) - case "mass": - w.ObjectKey("mass") - w.Float64(t.Mass) - case "friends": - w.ObjectKey("friends") - w.BeginArray() - for _, val := range t.Friends { - val.WriteJson(w) - } - w.EndArray() - case "friendsConnection": - w.ObjectKey("friendsConnection") - t.FriendsConnection.WriteJson(w) - case "appearsIn": - w.ObjectKey("appearsIn") - w.BeginArray() - for _, val := range t.AppearsIn { - w.String(val) - } - w.EndArray() - case "starships": - w.ObjectKey("starships") - w.BeginArray() - for _, val := range t.Starships { - val.WriteJson(w) - } - w.EndArray() - } - } - w.EndObject() -} - -type _MutationNode struct { - _fields []collectedField - CreateReview jsonw.JsonWriter + return out } var mutationImplementors = []string{"Mutation"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _mutation(sel []query.Selection, it *interface{}) jsonw.JsonWriter { - node := _MutationNode{ - _fields: ec.collectFields(sel, mutationImplementors, map[string]bool{}), - } +func (ec *executionContext) _mutation(sel []query.Selection, it *interface{}) jsonw.Writer { + fields := ec.collectFields(sel, mutationImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "createReview": var arg0 string @@ -548,115 +426,69 @@ func (ec *executionContext) _mutation(sel []query.Selection, it *interface{}) js continue } ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.Mutation_createReview(ec.ctx, arg0, arg1) if err != nil { ec.Error(err) return } - if res != nil { - node.CreateReview = ec._review(field.Selections, res) + + if res == nil { + out.Values[i] = jsonw.Null + } else { + out.Values[i] = ec._review(field.Selections, res) } - }(field) + }(i, field) default: panic("unknown field " + strconv.Quote(field.Name)) } } - return &node -} - -func (t *_MutationNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "createReview": - w.ObjectKey("createReview") - if t.CreateReview == nil { - w.Null() - } else { - t.CreateReview.WriteJson(w) - } - } - } - w.EndObject() -} - -type _PageInfoNode struct { - _fields []collectedField - StartCursor string - EndCursor string - HasNextPage bool + return out } var pageInfoImplementors = []string{"PageInfo"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _pageInfo(sel []query.Selection, it *PageInfo) jsonw.JsonWriter { - node := _PageInfoNode{ - _fields: ec.collectFields(sel, pageInfoImplementors, map[string]bool{}), - } +func (ec *executionContext) _pageInfo(sel []query.Selection, it *PageInfo) jsonw.Writer { + fields := ec.collectFields(sel, pageInfoImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "startCursor": res := it.StartCursor - node.StartCursor = res + + out.Values[i] = jsonw.String(res) case "endCursor": res := it.EndCursor - node.EndCursor = res + + out.Values[i] = jsonw.String(res) case "hasNextPage": res := it.HasNextPage - node.HasNextPage = res + + out.Values[i] = jsonw.Bool(res) default: panic("unknown field " + strconv.Quote(field.Name)) } } - return &node -} - -func (t *_PageInfoNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "startCursor": - w.ObjectKey("startCursor") - w.String(t.StartCursor) - case "endCursor": - w.ObjectKey("endCursor") - w.String(t.EndCursor) - case "hasNextPage": - w.ObjectKey("hasNextPage") - w.Bool(t.HasNextPage) - } - } - w.EndObject() -} - -type _QueryNode struct { - _fields []collectedField - Hero jsonw.JsonWriter - Reviews []jsonw.JsonWriter - Search []jsonw.JsonWriter - Character jsonw.JsonWriter - Droid jsonw.JsonWriter - Human jsonw.JsonWriter - Starship jsonw.JsonWriter - __schema jsonw.JsonWriter - __type jsonw.JsonWriter + return out } var queryImplementors = []string{"Query"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _query(sel []query.Selection, it *interface{}) jsonw.JsonWriter { - node := _QueryNode{ - _fields: ec.collectFields(sel, queryImplementors, map[string]bool{}), - } +func (ec *executionContext) _query(sel []query.Selection, it *interface{}) jsonw.Writer { + fields := ec.collectFields(sel, queryImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "hero": var arg0 *string @@ -669,15 +501,16 @@ func (ec *executionContext) _query(sel []query.Selection, it *interface{}) jsonw arg0 = &tmp2 } ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.Query_hero(ec.ctx, arg0) if err != nil { ec.Error(err) return } - node.Hero = ec._character(field.Selections, res) - }(field) + + out.Values[i] = ec._character(field.Selections, &res) + }(i, field) case "reviews": var arg0 string if tmp, ok := field.Args["episode"]; ok { @@ -703,19 +536,22 @@ func (ec *executionContext) _query(sel []query.Selection, it *interface{}) jsonw } } ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.Query_reviews(ec.ctx, arg0, arg1) if err != nil { ec.Error(err) return } - if res != nil { - for i := range res { - node.Reviews = append(node.Reviews, ec._review(field.Selections, &res[i])) - } + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + tmp1 = ec._review(field.Selections, &loopval1) + arr1 = append(arr1, tmp1) } - }(field) + out.Values[i] = arr1 + }(i, field) case "search": var arg0 string if tmp, ok := field.Args["text"]; ok { @@ -727,19 +563,22 @@ func (ec *executionContext) _query(sel []query.Selection, it *interface{}) jsonw arg0 = tmp2 } ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.Query_search(ec.ctx, arg0) if err != nil { ec.Error(err) return } - if res != nil { - for i := range res { - node.Search = append(node.Search, ec._searchResult(field.Selections, res[i])) - } + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + tmp1 = ec._searchResult(field.Selections, &loopval1) + arr1 = append(arr1, tmp1) } - }(field) + out.Values[i] = arr1 + }(i, field) case "character": var arg0 string if tmp, ok := field.Args["id"]; ok { @@ -751,15 +590,16 @@ func (ec *executionContext) _query(sel []query.Selection, it *interface{}) jsonw arg0 = tmp2 } ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.Query_character(ec.ctx, arg0) if err != nil { ec.Error(err) return } - node.Character = ec._character(field.Selections, res) - }(field) + + out.Values[i] = ec._character(field.Selections, &res) + }(i, field) case "droid": var arg0 string if tmp, ok := field.Args["id"]; ok { @@ -771,17 +611,20 @@ func (ec *executionContext) _query(sel []query.Selection, it *interface{}) jsonw arg0 = tmp2 } ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.Query_droid(ec.ctx, arg0) if err != nil { ec.Error(err) return } - if res != nil { - node.Droid = ec._droid(field.Selections, res) + + if res == nil { + out.Values[i] = jsonw.Null + } else { + out.Values[i] = ec._droid(field.Selections, res) } - }(field) + }(i, field) case "human": var arg0 string if tmp, ok := field.Args["id"]; ok { @@ -793,17 +636,20 @@ func (ec *executionContext) _query(sel []query.Selection, it *interface{}) jsonw arg0 = tmp2 } ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.Query_human(ec.ctx, arg0) if err != nil { ec.Error(err) return } - if res != nil { - node.Human = ec._human(field.Selections, res) + + if res == nil { + out.Values[i] = jsonw.Null + } else { + out.Values[i] = ec._human(field.Selections, res) } - }(field) + }(i, field) case "starship": var arg0 string if tmp, ok := field.Args["id"]; ok { @@ -815,21 +661,27 @@ func (ec *executionContext) _query(sel []query.Selection, it *interface{}) jsonw arg0 = tmp2 } ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.Query_starship(ec.ctx, arg0) if err != nil { ec.Error(err) return } - if res != nil { - node.Starship = ec._starship(field.Selections, res) + + if res == nil { + out.Values[i] = jsonw.Null + } else { + out.Values[i] = ec._starship(field.Selections, res) } - }(field) + }(i, field) case "__schema": res := ec.introspectSchema() - if res != nil { - node.__schema = ec.___Schema(field.Selections, res) + + if res == nil { + out.Values[i] = jsonw.Null + } else { + out.Values[i] = ec.___Schema(field.Selections, res) } case "__type": var arg0 string @@ -842,160 +694,74 @@ func (ec *executionContext) _query(sel []query.Selection, it *interface{}) jsonw arg0 = tmp2 } res := ec.introspectType(arg0) - if res != nil { - node.__type = ec.___Type(field.Selections, res) - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - - return &node -} -func (t *_QueryNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "hero": - w.ObjectKey("hero") - t.Hero.WriteJson(w) - case "reviews": - w.ObjectKey("reviews") - w.BeginArray() - for _, val := range t.Reviews { - val.WriteJson(w) - } - w.EndArray() - case "search": - w.ObjectKey("search") - w.BeginArray() - for _, val := range t.Search { - val.WriteJson(w) - } - w.EndArray() - case "character": - w.ObjectKey("character") - t.Character.WriteJson(w) - case "droid": - w.ObjectKey("droid") - if t.Droid == nil { - w.Null() - } else { - t.Droid.WriteJson(w) - } - case "human": - w.ObjectKey("human") - if t.Human == nil { - w.Null() + if res == nil { + out.Values[i] = jsonw.Null } else { - t.Human.WriteJson(w) - } - case "starship": - w.ObjectKey("starship") - if t.Starship == nil { - w.Null() - } else { - t.Starship.WriteJson(w) - } - case "__schema": - w.ObjectKey("__schema") - if t.__schema == nil { - w.Null() - } else { - t.__schema.WriteJson(w) - } - case "__type": - w.ObjectKey("__type") - if t.__type == nil { - w.Null() - } else { - t.__type.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type _ReviewNode struct { - _fields []collectedField - Stars int - Commentary *string - Time time.Time + return out } var reviewImplementors = []string{"Review"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _review(sel []query.Selection, it *Review) jsonw.JsonWriter { - node := _ReviewNode{ - _fields: ec.collectFields(sel, reviewImplementors, map[string]bool{}), - } +func (ec *executionContext) _review(sel []query.Selection, it *Review) jsonw.Writer { + fields := ec.collectFields(sel, reviewImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "stars": res := it.Stars - node.Stars = res + + out.Values[i] = jsonw.Int(res) case "commentary": res := it.Commentary - node.Commentary = res - case "time": - res := it.Time - node.Time = res - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - return &node -} - -func (t *_ReviewNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "stars": - w.ObjectKey("stars") - w.Int(t.Stars) - case "commentary": - w.ObjectKey("commentary") - if t.Commentary == nil { - w.Null() + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.Commentary) + out.Values[i] = jsonw.String(*res) } case "time": - w.ObjectKey("time") - w.Time(t.Time) + res := it.Time + + out.Values[i] = jsonw.Time(res) + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type _StarshipNode struct { - _fields []collectedField - Id string - Name string - Length float64 + return out } var starshipImplementors = []string{"Starship"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _starship(sel []query.Selection, it *Starship) jsonw.JsonWriter { - node := _StarshipNode{ - _fields: ec.collectFields(sel, starshipImplementors, map[string]bool{}), - } +func (ec *executionContext) _starship(sel []query.Selection, it *Starship) jsonw.Writer { + fields := ec.collectFields(sel, starshipImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "id": res := it.ID - node.Id = res + + out.Values[i] = jsonw.String(res) case "name": res := it.Name - node.Name = res + + out.Values[i] = jsonw.String(res) case "length": var arg0 string if tmp, ok := field.Args["unit"]; ok { @@ -1007,491 +773,332 @@ func (ec *executionContext) _starship(sel []query.Selection, it *Starship) jsonw arg0 = tmp2 } res := it.Length(arg0) - node.Length = res + + out.Values[i] = jsonw.Float64(res) default: panic("unknown field " + strconv.Quote(field.Name)) } } - return &node -} - -func (t *_StarshipNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "id": - w.ObjectKey("id") - w.String(t.Id) - case "name": - w.ObjectKey("name") - w.String(t.Name) - case "length": - w.ObjectKey("length") - w.Float64(t.Length) - } - } - w.EndObject() -} - -type ___DirectiveNode struct { - _fields []collectedField - Name string - Description *string - Locations []string - Args []jsonw.JsonWriter + return out } var __DirectiveImplementors = []string{"__Directive"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___Directive(sel []query.Selection, it *introspection.Directive) jsonw.JsonWriter { - node := ___DirectiveNode{ - _fields: ec.collectFields(sel, __DirectiveImplementors, map[string]bool{}), - } +func (ec *executionContext) ___Directive(sel []query.Selection, it *introspection.Directive) jsonw.Writer { + fields := ec.collectFields(sel, __DirectiveImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "name": res := it.Name() - node.Name = res + + out.Values[i] = jsonw.String(res) case "description": res := it.Description() - node.Description = res - case "locations": - res := it.Locations() - node.Locations = res - case "args": - res := it.Args() - if res != nil { - for i := range res { - node.Args = append(node.Args, ec.___InputValue(field.Selections, res[i])) - } - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - - return &node -} -func (t *___DirectiveNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "name": - w.ObjectKey("name") - w.String(t.Name) - case "description": - w.ObjectKey("description") - if t.Description == nil { - w.Null() + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.Description) + out.Values[i] = jsonw.String(*res) } case "locations": - w.ObjectKey("locations") - w.BeginArray() - for _, val := range t.Locations { - w.String(val) + res := it.Locations() + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + tmp1 = jsonw.String(loopval1) + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 case "args": - w.ObjectKey("args") - w.BeginArray() - for _, val := range t.Args { - if val == nil { - w.Null() + res := it.Args() + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___InputValue(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type ___EnumValueNode struct { - _fields []collectedField - Name string - Description *string - IsDeprecated bool - DeprecationReason *string + return out } var __EnumValueImplementors = []string{"__EnumValue"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___EnumValue(sel []query.Selection, it *introspection.EnumValue) jsonw.JsonWriter { - node := ___EnumValueNode{ - _fields: ec.collectFields(sel, __EnumValueImplementors, map[string]bool{}), - } +func (ec *executionContext) ___EnumValue(sel []query.Selection, it *introspection.EnumValue) jsonw.Writer { + fields := ec.collectFields(sel, __EnumValueImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "name": res := it.Name() - node.Name = res + + out.Values[i] = jsonw.String(res) case "description": res := it.Description() - node.Description = res - case "isDeprecated": - res := it.IsDeprecated() - node.IsDeprecated = res - case "deprecationReason": - res := it.DeprecationReason() - node.DeprecationReason = res - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - - return &node -} -func (t *___EnumValueNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "name": - w.ObjectKey("name") - w.String(t.Name) - case "description": - w.ObjectKey("description") - if t.Description == nil { - w.Null() + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.Description) + out.Values[i] = jsonw.String(*res) } case "isDeprecated": - w.ObjectKey("isDeprecated") - w.Bool(t.IsDeprecated) + res := it.IsDeprecated() + + out.Values[i] = jsonw.Bool(res) case "deprecationReason": - w.ObjectKey("deprecationReason") - if t.DeprecationReason == nil { - w.Null() + res := it.DeprecationReason() + + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.DeprecationReason) + out.Values[i] = jsonw.String(*res) } + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type ___FieldNode struct { - _fields []collectedField - Name string - Description *string - Args []jsonw.JsonWriter - Type jsonw.JsonWriter - IsDeprecated bool - DeprecationReason *string + return out } var __FieldImplementors = []string{"__Field"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___Field(sel []query.Selection, it *introspection.Field) jsonw.JsonWriter { - node := ___FieldNode{ - _fields: ec.collectFields(sel, __FieldImplementors, map[string]bool{}), - } +func (ec *executionContext) ___Field(sel []query.Selection, it *introspection.Field) jsonw.Writer { + fields := ec.collectFields(sel, __FieldImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "name": res := it.Name() - node.Name = res + + out.Values[i] = jsonw.String(res) case "description": res := it.Description() - node.Description = res - case "args": - res := it.Args() - if res != nil { - for i := range res { - node.Args = append(node.Args, ec.___InputValue(field.Selections, res[i])) - } - } - case "type": - res := it.Type() - if res != nil { - node.Type = ec.___Type(field.Selections, res) - } - case "isDeprecated": - res := it.IsDeprecated() - node.IsDeprecated = res - case "deprecationReason": - res := it.DeprecationReason() - node.DeprecationReason = res - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - return &node -} - -func (t *___FieldNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "name": - w.ObjectKey("name") - w.String(t.Name) - case "description": - w.ObjectKey("description") - if t.Description == nil { - w.Null() + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.Description) + out.Values[i] = jsonw.String(*res) } case "args": - w.ObjectKey("args") - w.BeginArray() - for _, val := range t.Args { - if val == nil { - w.Null() + res := it.Args() + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___InputValue(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 case "type": - w.ObjectKey("type") - if t.Type == nil { - w.Null() + res := it.Type() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.Type.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } case "isDeprecated": - w.ObjectKey("isDeprecated") - w.Bool(t.IsDeprecated) + res := it.IsDeprecated() + + out.Values[i] = jsonw.Bool(res) case "deprecationReason": - w.ObjectKey("deprecationReason") - if t.DeprecationReason == nil { - w.Null() + res := it.DeprecationReason() + + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.DeprecationReason) + out.Values[i] = jsonw.String(*res) } + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type ___InputValueNode struct { - _fields []collectedField - Name string - Description *string - Type jsonw.JsonWriter - DefaultValue *string + return out } var __InputValueImplementors = []string{"__InputValue"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___InputValue(sel []query.Selection, it *introspection.InputValue) jsonw.JsonWriter { - node := ___InputValueNode{ - _fields: ec.collectFields(sel, __InputValueImplementors, map[string]bool{}), - } +func (ec *executionContext) ___InputValue(sel []query.Selection, it *introspection.InputValue) jsonw.Writer { + fields := ec.collectFields(sel, __InputValueImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "name": res := it.Name() - node.Name = res + + out.Values[i] = jsonw.String(res) case "description": res := it.Description() - node.Description = res - case "type": - res := it.Type() - if res != nil { - node.Type = ec.___Type(field.Selections, res) - } - case "defaultValue": - res := it.DefaultValue() - node.DefaultValue = res - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - return &node -} - -func (t *___InputValueNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "name": - w.ObjectKey("name") - w.String(t.Name) - case "description": - w.ObjectKey("description") - if t.Description == nil { - w.Null() + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.Description) + out.Values[i] = jsonw.String(*res) } case "type": - w.ObjectKey("type") - if t.Type == nil { - w.Null() + res := it.Type() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.Type.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } case "defaultValue": - w.ObjectKey("defaultValue") - if t.DefaultValue == nil { - w.Null() + res := it.DefaultValue() + + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.DefaultValue) + out.Values[i] = jsonw.String(*res) } + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type ___SchemaNode struct { - _fields []collectedField - Types []jsonw.JsonWriter - QueryType jsonw.JsonWriter - MutationType jsonw.JsonWriter - SubscriptionType jsonw.JsonWriter - Directives []jsonw.JsonWriter + return out } var __SchemaImplementors = []string{"__Schema"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___Schema(sel []query.Selection, it *introspection.Schema) jsonw.JsonWriter { - node := ___SchemaNode{ - _fields: ec.collectFields(sel, __SchemaImplementors, map[string]bool{}), - } +func (ec *executionContext) ___Schema(sel []query.Selection, it *introspection.Schema) jsonw.Writer { + fields := ec.collectFields(sel, __SchemaImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "types": res := it.Types() - if res != nil { - for i := range res { - node.Types = append(node.Types, ec.___Type(field.Selections, res[i])) - } - } - case "queryType": - res := it.QueryType() - if res != nil { - node.QueryType = ec.___Type(field.Selections, res) - } - case "mutationType": - res := it.MutationType() - if res != nil { - node.MutationType = ec.___Type(field.Selections, res) - } - case "subscriptionType": - res := it.SubscriptionType() - if res != nil { - node.SubscriptionType = ec.___Type(field.Selections, res) - } - case "directives": - res := it.Directives() - if res != nil { - for i := range res { - node.Directives = append(node.Directives, ec.___Directive(field.Selections, res[i])) - } - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - return &node -} + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer -func (t *___SchemaNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "types": - w.ObjectKey("types") - w.BeginArray() - for _, val := range t.Types { - if val == nil { - w.Null() + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___Type(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 case "queryType": - w.ObjectKey("queryType") - if t.QueryType == nil { - w.Null() + res := it.QueryType() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.QueryType.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } case "mutationType": - w.ObjectKey("mutationType") - if t.MutationType == nil { - w.Null() + res := it.MutationType() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.MutationType.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } case "subscriptionType": - w.ObjectKey("subscriptionType") - if t.SubscriptionType == nil { - w.Null() + res := it.SubscriptionType() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.SubscriptionType.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } case "directives": - w.ObjectKey("directives") - w.BeginArray() - for _, val := range t.Directives { - if val == nil { - w.Null() + res := it.Directives() + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___Directive(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type ___TypeNode struct { - _fields []collectedField - Kind string - Name *string - Description *string - Fields []jsonw.JsonWriter - Interfaces []jsonw.JsonWriter - PossibleTypes []jsonw.JsonWriter - EnumValues []jsonw.JsonWriter - InputFields []jsonw.JsonWriter - OfType jsonw.JsonWriter + return out } var __TypeImplementors = []string{"__Type"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___Type(sel []query.Selection, it *introspection.Type) jsonw.JsonWriter { - node := ___TypeNode{ - _fields: ec.collectFields(sel, __TypeImplementors, map[string]bool{}), - } +func (ec *executionContext) ___Type(sel []query.Selection, it *introspection.Type) jsonw.Writer { + fields := ec.collectFields(sel, __TypeImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "kind": res := it.Kind() - node.Kind = res + + out.Values[i] = jsonw.String(res) case "name": res := it.Name() - node.Name = res + + if res == nil { + out.Values[i] = jsonw.Null + } else { + out.Values[i] = jsonw.String(*res) + } case "description": res := it.Description() - node.Description = res + + if res == nil { + out.Values[i] = jsonw.Null + } else { + out.Values[i] = jsonw.String(*res) + } case "fields": var arg0 bool if tmp, ok := field.Args["includeDeprecated"]; ok { @@ -1503,25 +1110,49 @@ func (ec *executionContext) ___Type(sel []query.Selection, it *introspection.Typ arg0 = tmp2 } res := it.Fields(arg0) - if res != nil { - for i := range res { - node.Fields = append(node.Fields, ec.___Field(field.Selections, res[i])) + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null + } else { + tmp1 = ec.___Field(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } + out.Values[i] = arr1 case "interfaces": res := it.Interfaces() - if res != nil { - for i := range res { - node.Interfaces = append(node.Interfaces, ec.___Type(field.Selections, res[i])) + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null + } else { + tmp1 = ec.___Type(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } + out.Values[i] = arr1 case "possibleTypes": res := it.PossibleTypes() - if res != nil { - for i := range res { - node.PossibleTypes = append(node.PossibleTypes, ec.___Type(field.Selections, res[i])) + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null + } else { + tmp1 = ec.___Type(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } + out.Values[i] = arr1 case "enumValues": var arg0 bool if tmp, ok := field.Args["includeDeprecated"]; ok { @@ -1533,123 +1164,54 @@ func (ec *executionContext) ___Type(sel []query.Selection, it *introspection.Typ arg0 = tmp2 } res := it.EnumValues(arg0) - if res != nil { - for i := range res { - node.EnumValues = append(node.EnumValues, ec.___EnumValue(field.Selections, res[i])) - } - } - case "inputFields": - res := it.InputFields() - if res != nil { - for i := range res { - node.InputFields = append(node.InputFields, ec.___InputValue(field.Selections, res[i])) - } - } - case "ofType": - res := it.OfType() - if res != nil { - node.OfType = ec.___Type(field.Selections, res) - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - return &node -} + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer -func (t *___TypeNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "kind": - w.ObjectKey("kind") - w.String(t.Kind) - case "name": - w.ObjectKey("name") - if t.Name == nil { - w.Null() - } else { - w.String(*t.Name) - } - case "description": - w.ObjectKey("description") - if t.Description == nil { - w.Null() - } else { - w.String(*t.Description) - } - case "fields": - w.ObjectKey("fields") - w.BeginArray() - for _, val := range t.Fields { - if val == nil { - w.Null() - } else { - val.WriteJson(w) - } - } - w.EndArray() - case "interfaces": - w.ObjectKey("interfaces") - w.BeginArray() - for _, val := range t.Interfaces { - if val == nil { - w.Null() - } else { - val.WriteJson(w) - } - } - w.EndArray() - case "possibleTypes": - w.ObjectKey("possibleTypes") - w.BeginArray() - for _, val := range t.PossibleTypes { - if val == nil { - w.Null() + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___EnumValue(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() - case "enumValues": - w.ObjectKey("enumValues") - w.BeginArray() - for _, val := range t.EnumValues { - if val == nil { - w.Null() - } else { - val.WriteJson(w) - } - } - w.EndArray() + out.Values[i] = arr1 case "inputFields": - w.ObjectKey("inputFields") - w.BeginArray() - for _, val := range t.InputFields { - if val == nil { - w.Null() + res := it.InputFields() + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___InputValue(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 case "ofType": - w.ObjectKey("ofType") - if t.OfType == nil { - w.Null() + res := it.OfType() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.OfType.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() + + return out } -func (ec *executionContext) _character(sel []query.Selection, it Character) jsonw.JsonWriter { - switch it := it.(type) { +func (ec *executionContext) _character(sel []query.Selection, it *Character) jsonw.Writer { + switch it := (*it).(type) { case nil: - return jsonw.NullWriter + return jsonw.Null case Human: return ec._human(sel, &it) @@ -1665,10 +1227,10 @@ func (ec *executionContext) _character(sel []query.Selection, it Character) json } } -func (ec *executionContext) _searchResult(sel []query.Selection, it SearchResult) jsonw.JsonWriter { - switch it := it.(type) { +func (ec *executionContext) _searchResult(sel []query.Selection, it *SearchResult) jsonw.Writer { + switch it := (*it).(type) { case nil: - return jsonw.NullWriter + return jsonw.Null case Human: return ec._human(sel, &it) diff --git a/example/starwars/starwars.go b/example/starwars/starwars.go index e650aab766e..5bd1dcf5d6e 100644 --- a/example/starwars/starwars.go +++ b/example/starwars/starwars.go @@ -83,6 +83,8 @@ func (r *Resolver) FriendsConnection_friends(ctx context.Context, it *FriendsCon } func (r *Resolver) Mutation_createReview(ctx context.Context, episode string, review Review) (*Review, error) { + review.Time = time.Now() + time.Sleep(1 * time.Second) r.reviews[episode] = append(r.reviews[episode], review) return &review, nil } diff --git a/example/todo/generated.go b/example/todo/generated.go index c053fa2b666..6e75ca3f48b 100644 --- a/example/todo/generated.go +++ b/example/todo/generated.go @@ -53,29 +53,25 @@ func NewExecutor(resolvers Resolvers) func(context.Context, string, string, map[ ctx: ctx, } - var result jsonw.JsonWriter + var data jsonw.Writer if op.Type == query.Query { - result = c._myQuery(op.Selections, nil) + data = c._myQuery(op.Selections, nil) } else if op.Type == query.Mutation { - result = c._myMutation(op.Selections, nil) + data = c._myMutation(op.Selections, nil) } else { return []*errors.QueryError{errors.Errorf("unsupported operation type")} } c.wg.Wait() - writer := jsonw.New(w) - writer.BeginObject() - - writer.ObjectKey("data") - result.WriteJson(writer) + result := &jsonw.OrderedMap{} + result.Add("data", data) if len(c.Errors) > 0 { - writer.ObjectKey("errors") - errors.WriteErrors(w, c.Errors) + result.Add("errors", errors.ErrorWriter(c.Errors)) } - writer.EndObject() + result.WriteJson(w) return nil } } @@ -89,21 +85,16 @@ type executionContext struct { wg sync.WaitGroup } -type _MyMutationNode struct { - _fields []collectedField - CreateTodo jsonw.JsonWriter - UpdateTodo jsonw.JsonWriter -} - var myMutationImplementors = []string{"MyMutation"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _myMutation(sel []query.Selection, it *interface{}) jsonw.JsonWriter { - node := _MyMutationNode{ - _fields: ec.collectFields(sel, myMutationImplementors, map[string]bool{}), - } +func (ec *executionContext) _myMutation(sel []query.Selection, it *interface{}) jsonw.Writer { + fields := ec.collectFields(sel, myMutationImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "createTodo": var arg0 string @@ -116,15 +107,16 @@ func (ec *executionContext) _myMutation(sel []query.Selection, it *interface{}) arg0 = tmp2 } ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.MyMutation_createTodo(ec.ctx, arg0) if err != nil { ec.Error(err) return } - node.CreateTodo = ec._todo(field.Selections, &res) - }(field) + + out.Values[i] = ec._todo(field.Selections, &res) + }(i, field) case "updateTodo": var arg0 int if tmp, ok := field.Args["id"]; ok { @@ -140,62 +132,38 @@ func (ec *executionContext) _myMutation(sel []query.Selection, it *interface{}) arg1 = tmp.(map[string]interface{}) } ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.MyMutation_updateTodo(ec.ctx, arg0, arg1) if err != nil { ec.Error(err) return } - if res != nil { - node.UpdateTodo = ec._todo(field.Selections, res) + + if res == nil { + out.Values[i] = jsonw.Null + } else { + out.Values[i] = ec._todo(field.Selections, res) } - }(field) + }(i, field) default: panic("unknown field " + strconv.Quote(field.Name)) } } - return &node -} - -func (t *_MyMutationNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "createTodo": - w.ObjectKey("createTodo") - t.CreateTodo.WriteJson(w) - case "updateTodo": - w.ObjectKey("updateTodo") - if t.UpdateTodo == nil { - w.Null() - } else { - t.UpdateTodo.WriteJson(w) - } - } - } - w.EndObject() -} - -type _MyQueryNode struct { - _fields []collectedField - Todo jsonw.JsonWriter - LastTodo jsonw.JsonWriter - Todos []jsonw.JsonWriter - __schema jsonw.JsonWriter - __type jsonw.JsonWriter + return out } var myQueryImplementors = []string{"MyQuery"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _myQuery(sel []query.Selection, it *interface{}) jsonw.JsonWriter { - node := _MyQueryNode{ - _fields: ec.collectFields(sel, myQueryImplementors, map[string]bool{}), - } +func (ec *executionContext) _myQuery(sel []query.Selection, it *interface{}) jsonw.Writer { + fields := ec.collectFields(sel, myQueryImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "todo": var arg0 int @@ -208,49 +176,61 @@ func (ec *executionContext) _myQuery(sel []query.Selection, it *interface{}) jso arg0 = tmp2 } ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.MyQuery_todo(ec.ctx, arg0) if err != nil { ec.Error(err) return } - if res != nil { - node.Todo = ec._todo(field.Selections, res) + + if res == nil { + out.Values[i] = jsonw.Null + } else { + out.Values[i] = ec._todo(field.Selections, res) } - }(field) + }(i, field) case "lastTodo": ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.MyQuery_lastTodo(ec.ctx) if err != nil { ec.Error(err) return } - if res != nil { - node.LastTodo = ec._todo(field.Selections, res) + + if res == nil { + out.Values[i] = jsonw.Null + } else { + out.Values[i] = ec._todo(field.Selections, res) } - }(field) + }(i, field) case "todos": ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() res, err := ec.resolvers.MyQuery_todos(ec.ctx) if err != nil { ec.Error(err) return } - if res != nil { - for i := range res { - node.Todos = append(node.Todos, ec._todo(field.Selections, &res[i])) - } + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + tmp1 = ec._todo(field.Selections, &loopval1) + arr1 = append(arr1, tmp1) } - }(field) + out.Values[i] = arr1 + }(i, field) case "__schema": res := ec.introspectSchema() - if res != nil { - node.__schema = ec.___Schema(field.Selections, res) + + if res == nil { + out.Values[i] = jsonw.Null + } else { + out.Values[i] = ec.___Schema(field.Selections, res) } case "__type": var arg0 string @@ -263,571 +243,367 @@ func (ec *executionContext) _myQuery(sel []query.Selection, it *interface{}) jso arg0 = tmp2 } res := ec.introspectType(arg0) - if res != nil { - node.__type = ec.___Type(field.Selections, res) - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - - return &node -} -func (t *_MyQueryNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "todo": - w.ObjectKey("todo") - if t.Todo == nil { - w.Null() + if res == nil { + out.Values[i] = jsonw.Null } else { - t.Todo.WriteJson(w) - } - case "lastTodo": - w.ObjectKey("lastTodo") - if t.LastTodo == nil { - w.Null() - } else { - t.LastTodo.WriteJson(w) - } - case "todos": - w.ObjectKey("todos") - w.BeginArray() - for _, val := range t.Todos { - val.WriteJson(w) - } - w.EndArray() - case "__schema": - w.ObjectKey("__schema") - if t.__schema == nil { - w.Null() - } else { - t.__schema.WriteJson(w) - } - case "__type": - w.ObjectKey("__type") - if t.__type == nil { - w.Null() - } else { - t.__type.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type _TodoNode struct { - _fields []collectedField - Id int - Text string - Done bool + return out } var todoImplementors = []string{"Todo"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _todo(sel []query.Selection, it *Todo) jsonw.JsonWriter { - node := _TodoNode{ - _fields: ec.collectFields(sel, todoImplementors, map[string]bool{}), - } +func (ec *executionContext) _todo(sel []query.Selection, it *Todo) jsonw.Writer { + fields := ec.collectFields(sel, todoImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "id": res := it.ID - node.Id = res + + out.Values[i] = jsonw.Int(res) case "text": res := it.Text - node.Text = res + + out.Values[i] = jsonw.String(res) case "done": res := it.Done - node.Done = res + + out.Values[i] = jsonw.Bool(res) default: panic("unknown field " + strconv.Quote(field.Name)) } } - return &node -} - -func (t *_TodoNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "id": - w.ObjectKey("id") - w.Int(t.Id) - case "text": - w.ObjectKey("text") - w.String(t.Text) - case "done": - w.ObjectKey("done") - w.Bool(t.Done) - } - } - w.EndObject() -} - -type ___DirectiveNode struct { - _fields []collectedField - Name string - Description *string - Locations []string - Args []jsonw.JsonWriter + return out } var __DirectiveImplementors = []string{"__Directive"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___Directive(sel []query.Selection, it *introspection.Directive) jsonw.JsonWriter { - node := ___DirectiveNode{ - _fields: ec.collectFields(sel, __DirectiveImplementors, map[string]bool{}), - } +func (ec *executionContext) ___Directive(sel []query.Selection, it *introspection.Directive) jsonw.Writer { + fields := ec.collectFields(sel, __DirectiveImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "name": res := it.Name() - node.Name = res + + out.Values[i] = jsonw.String(res) case "description": res := it.Description() - node.Description = res - case "locations": - res := it.Locations() - node.Locations = res - case "args": - res := it.Args() - if res != nil { - for i := range res { - node.Args = append(node.Args, ec.___InputValue(field.Selections, res[i])) - } - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - - return &node -} -func (t *___DirectiveNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "name": - w.ObjectKey("name") - w.String(t.Name) - case "description": - w.ObjectKey("description") - if t.Description == nil { - w.Null() + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.Description) + out.Values[i] = jsonw.String(*res) } case "locations": - w.ObjectKey("locations") - w.BeginArray() - for _, val := range t.Locations { - w.String(val) + res := it.Locations() + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + tmp1 = jsonw.String(loopval1) + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 case "args": - w.ObjectKey("args") - w.BeginArray() - for _, val := range t.Args { - if val == nil { - w.Null() + res := it.Args() + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___InputValue(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type ___EnumValueNode struct { - _fields []collectedField - Name string - Description *string - IsDeprecated bool - DeprecationReason *string + return out } var __EnumValueImplementors = []string{"__EnumValue"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___EnumValue(sel []query.Selection, it *introspection.EnumValue) jsonw.JsonWriter { - node := ___EnumValueNode{ - _fields: ec.collectFields(sel, __EnumValueImplementors, map[string]bool{}), - } +func (ec *executionContext) ___EnumValue(sel []query.Selection, it *introspection.EnumValue) jsonw.Writer { + fields := ec.collectFields(sel, __EnumValueImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "name": res := it.Name() - node.Name = res + + out.Values[i] = jsonw.String(res) case "description": res := it.Description() - node.Description = res - case "isDeprecated": - res := it.IsDeprecated() - node.IsDeprecated = res - case "deprecationReason": - res := it.DeprecationReason() - node.DeprecationReason = res - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - return &node -} - -func (t *___EnumValueNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "name": - w.ObjectKey("name") - w.String(t.Name) - case "description": - w.ObjectKey("description") - if t.Description == nil { - w.Null() + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.Description) + out.Values[i] = jsonw.String(*res) } case "isDeprecated": - w.ObjectKey("isDeprecated") - w.Bool(t.IsDeprecated) + res := it.IsDeprecated() + + out.Values[i] = jsonw.Bool(res) case "deprecationReason": - w.ObjectKey("deprecationReason") - if t.DeprecationReason == nil { - w.Null() + res := it.DeprecationReason() + + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.DeprecationReason) + out.Values[i] = jsonw.String(*res) } + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type ___FieldNode struct { - _fields []collectedField - Name string - Description *string - Args []jsonw.JsonWriter - Type jsonw.JsonWriter - IsDeprecated bool - DeprecationReason *string + return out } var __FieldImplementors = []string{"__Field"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___Field(sel []query.Selection, it *introspection.Field) jsonw.JsonWriter { - node := ___FieldNode{ - _fields: ec.collectFields(sel, __FieldImplementors, map[string]bool{}), - } +func (ec *executionContext) ___Field(sel []query.Selection, it *introspection.Field) jsonw.Writer { + fields := ec.collectFields(sel, __FieldImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "name": res := it.Name() - node.Name = res + + out.Values[i] = jsonw.String(res) case "description": res := it.Description() - node.Description = res - case "args": - res := it.Args() - if res != nil { - for i := range res { - node.Args = append(node.Args, ec.___InputValue(field.Selections, res[i])) - } - } - case "type": - res := it.Type() - if res != nil { - node.Type = ec.___Type(field.Selections, res) - } - case "isDeprecated": - res := it.IsDeprecated() - node.IsDeprecated = res - case "deprecationReason": - res := it.DeprecationReason() - node.DeprecationReason = res - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - return &node -} - -func (t *___FieldNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "name": - w.ObjectKey("name") - w.String(t.Name) - case "description": - w.ObjectKey("description") - if t.Description == nil { - w.Null() + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.Description) + out.Values[i] = jsonw.String(*res) } case "args": - w.ObjectKey("args") - w.BeginArray() - for _, val := range t.Args { - if val == nil { - w.Null() + res := it.Args() + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___InputValue(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 case "type": - w.ObjectKey("type") - if t.Type == nil { - w.Null() + res := it.Type() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.Type.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } case "isDeprecated": - w.ObjectKey("isDeprecated") - w.Bool(t.IsDeprecated) + res := it.IsDeprecated() + + out.Values[i] = jsonw.Bool(res) case "deprecationReason": - w.ObjectKey("deprecationReason") - if t.DeprecationReason == nil { - w.Null() + res := it.DeprecationReason() + + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.DeprecationReason) + out.Values[i] = jsonw.String(*res) } + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type ___InputValueNode struct { - _fields []collectedField - Name string - Description *string - Type jsonw.JsonWriter - DefaultValue *string + return out } var __InputValueImplementors = []string{"__InputValue"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___InputValue(sel []query.Selection, it *introspection.InputValue) jsonw.JsonWriter { - node := ___InputValueNode{ - _fields: ec.collectFields(sel, __InputValueImplementors, map[string]bool{}), - } +func (ec *executionContext) ___InputValue(sel []query.Selection, it *introspection.InputValue) jsonw.Writer { + fields := ec.collectFields(sel, __InputValueImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "name": res := it.Name() - node.Name = res + + out.Values[i] = jsonw.String(res) case "description": res := it.Description() - node.Description = res - case "type": - res := it.Type() - if res != nil { - node.Type = ec.___Type(field.Selections, res) - } - case "defaultValue": - res := it.DefaultValue() - node.DefaultValue = res - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - - return &node -} -func (t *___InputValueNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "name": - w.ObjectKey("name") - w.String(t.Name) - case "description": - w.ObjectKey("description") - if t.Description == nil { - w.Null() + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.Description) + out.Values[i] = jsonw.String(*res) } case "type": - w.ObjectKey("type") - if t.Type == nil { - w.Null() + res := it.Type() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.Type.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } case "defaultValue": - w.ObjectKey("defaultValue") - if t.DefaultValue == nil { - w.Null() + res := it.DefaultValue() + + if res == nil { + out.Values[i] = jsonw.Null } else { - w.String(*t.DefaultValue) + out.Values[i] = jsonw.String(*res) } + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type ___SchemaNode struct { - _fields []collectedField - Types []jsonw.JsonWriter - QueryType jsonw.JsonWriter - MutationType jsonw.JsonWriter - SubscriptionType jsonw.JsonWriter - Directives []jsonw.JsonWriter + return out } var __SchemaImplementors = []string{"__Schema"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___Schema(sel []query.Selection, it *introspection.Schema) jsonw.JsonWriter { - node := ___SchemaNode{ - _fields: ec.collectFields(sel, __SchemaImplementors, map[string]bool{}), - } +func (ec *executionContext) ___Schema(sel []query.Selection, it *introspection.Schema) jsonw.Writer { + fields := ec.collectFields(sel, __SchemaImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "types": res := it.Types() - if res != nil { - for i := range res { - node.Types = append(node.Types, ec.___Type(field.Selections, res[i])) - } - } - case "queryType": - res := it.QueryType() - if res != nil { - node.QueryType = ec.___Type(field.Selections, res) - } - case "mutationType": - res := it.MutationType() - if res != nil { - node.MutationType = ec.___Type(field.Selections, res) - } - case "subscriptionType": - res := it.SubscriptionType() - if res != nil { - node.SubscriptionType = ec.___Type(field.Selections, res) - } - case "directives": - res := it.Directives() - if res != nil { - for i := range res { - node.Directives = append(node.Directives, ec.___Directive(field.Selections, res[i])) - } - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - return &node -} + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer -func (t *___SchemaNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "types": - w.ObjectKey("types") - w.BeginArray() - for _, val := range t.Types { - if val == nil { - w.Null() + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___Type(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 case "queryType": - w.ObjectKey("queryType") - if t.QueryType == nil { - w.Null() + res := it.QueryType() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.QueryType.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } case "mutationType": - w.ObjectKey("mutationType") - if t.MutationType == nil { - w.Null() + res := it.MutationType() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.MutationType.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } case "subscriptionType": - w.ObjectKey("subscriptionType") - if t.SubscriptionType == nil { - w.Null() + res := it.SubscriptionType() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.SubscriptionType.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } case "directives": - w.ObjectKey("directives") - w.BeginArray() - for _, val := range t.Directives { - if val == nil { - w.Null() + res := it.Directives() + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___Directive(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() -} -type ___TypeNode struct { - _fields []collectedField - Kind string - Name *string - Description *string - Fields []jsonw.JsonWriter - Interfaces []jsonw.JsonWriter - PossibleTypes []jsonw.JsonWriter - EnumValues []jsonw.JsonWriter - InputFields []jsonw.JsonWriter - OfType jsonw.JsonWriter + return out } var __TypeImplementors = []string{"__Type"} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) ___Type(sel []query.Selection, it *introspection.Type) jsonw.JsonWriter { - node := ___TypeNode{ - _fields: ec.collectFields(sel, __TypeImplementors, map[string]bool{}), - } +func (ec *executionContext) ___Type(sel []query.Selection, it *introspection.Type) jsonw.Writer { + fields := ec.collectFields(sel, __TypeImplementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { case "kind": res := it.Kind() - node.Kind = res + + out.Values[i] = jsonw.String(res) case "name": res := it.Name() - node.Name = res + + if res == nil { + out.Values[i] = jsonw.Null + } else { + out.Values[i] = jsonw.String(*res) + } case "description": res := it.Description() - node.Description = res + + if res == nil { + out.Values[i] = jsonw.Null + } else { + out.Values[i] = jsonw.String(*res) + } case "fields": var arg0 bool if tmp, ok := field.Args["includeDeprecated"]; ok { @@ -839,25 +615,49 @@ func (ec *executionContext) ___Type(sel []query.Selection, it *introspection.Typ arg0 = tmp2 } res := it.Fields(arg0) - if res != nil { - for i := range res { - node.Fields = append(node.Fields, ec.___Field(field.Selections, res[i])) + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null + } else { + tmp1 = ec.___Field(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } + out.Values[i] = arr1 case "interfaces": res := it.Interfaces() - if res != nil { - for i := range res { - node.Interfaces = append(node.Interfaces, ec.___Type(field.Selections, res[i])) + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null + } else { + tmp1 = ec.___Type(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } + out.Values[i] = arr1 case "possibleTypes": res := it.PossibleTypes() - if res != nil { - for i := range res { - node.PossibleTypes = append(node.PossibleTypes, ec.___Type(field.Selections, res[i])) + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null + } else { + tmp1 = ec.___Type(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } + out.Values[i] = arr1 case "enumValues": var arg0 bool if tmp, ok := field.Args["includeDeprecated"]; ok { @@ -869,117 +669,48 @@ func (ec *executionContext) ___Type(sel []query.Selection, it *introspection.Typ arg0 = tmp2 } res := it.EnumValues(arg0) - if res != nil { - for i := range res { - node.EnumValues = append(node.EnumValues, ec.___EnumValue(field.Selections, res[i])) - } - } - case "inputFields": - res := it.InputFields() - if res != nil { - for i := range res { - node.InputFields = append(node.InputFields, ec.___InputValue(field.Selections, res[i])) - } - } - case "ofType": - res := it.OfType() - if res != nil { - node.OfType = ec.___Type(field.Selections, res) - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - return &node -} + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer -func (t *___TypeNode) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - case "kind": - w.ObjectKey("kind") - w.String(t.Kind) - case "name": - w.ObjectKey("name") - if t.Name == nil { - w.Null() - } else { - w.String(*t.Name) - } - case "description": - w.ObjectKey("description") - if t.Description == nil { - w.Null() - } else { - w.String(*t.Description) - } - case "fields": - w.ObjectKey("fields") - w.BeginArray() - for _, val := range t.Fields { - if val == nil { - w.Null() - } else { - val.WriteJson(w) - } - } - w.EndArray() - case "interfaces": - w.ObjectKey("interfaces") - w.BeginArray() - for _, val := range t.Interfaces { - if val == nil { - w.Null() + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___EnumValue(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() - case "possibleTypes": - w.ObjectKey("possibleTypes") - w.BeginArray() - for _, val := range t.PossibleTypes { - if val == nil { - w.Null() - } else { - val.WriteJson(w) - } - } - w.EndArray() - case "enumValues": - w.ObjectKey("enumValues") - w.BeginArray() - for _, val := range t.EnumValues { - if val == nil { - w.Null() - } else { - val.WriteJson(w) - } - } - w.EndArray() + out.Values[i] = arr1 case "inputFields": - w.ObjectKey("inputFields") - w.BeginArray() - for _, val := range t.InputFields { - if val == nil { - w.Null() + res := it.InputFields() + + arr1 := jsonw.Array{} + for _, loopval1 := range res { + var tmp1 jsonw.Writer + + if loopval1 == nil { + tmp1 = jsonw.Null } else { - val.WriteJson(w) + tmp1 = ec.___InputValue(field.Selections, loopval1) } + arr1 = append(arr1, tmp1) } - w.EndArray() + out.Values[i] = arr1 case "ofType": - w.ObjectKey("ofType") - if t.OfType == nil { - w.Null() + res := it.OfType() + + if res == nil { + out.Values[i] = jsonw.Null } else { - t.OfType.WriteJson(w) + out.Values[i] = ec.___Type(field.Selections, res) } + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - w.EndObject() + + return out } var parsedSchema = schema.MustParse("schema {\n\tquery: MyQuery\n\tmutation: MyMutation\n}\n\ntype MyQuery {\n\ttodo(id: Int!): Todo\n\tlastTodo: Todo\n\ttodos: [Todo!]!\n}\n\ntype MyMutation {\n\tcreateTodo(text: String!): Todo!\n\tupdateTodo(id: Int!, changes: TodoInput!): Todo\n}\n\ntype Todo {\n\tid: Int!\n\ttext: String!\n\tdone: Boolean!\n}\n\ninput TodoInput {\n\ttext: String\n\tdone: Boolean\n}\n") diff --git a/example/todo/todo_test.go b/example/todo/todo_test.go index fc42fec2338..6fa91ba45f0 100644 --- a/example/todo/todo_test.go +++ b/example/todo/todo_test.go @@ -42,6 +42,20 @@ func TestTodo(t *testing.T) { require.Equal(t, "Very important", resp.UpdateTodo.Text) }) + t.Run("select with alias", func(t *testing.T) { + var resp struct { + A Todo + B Todo + } + c.MustPost(`{ a: todo(id:1) { text } b: todo(id:2) { id } }`, &resp) + + require.Equal(t, "A todo not to forget", resp.A.Text) + require.Equal(t, 0, resp.A.ID) + + require.Equal(t, "", resp.B.Text) + require.Equal(t, 2, resp.B.ID) + }) + t.Run("select all", func(t *testing.T) { var resp struct { Todo Todo diff --git a/jsonw/jsonw.go b/jsonw/jsonw.go new file mode 100644 index 00000000000..e9e2ecdf1d6 --- /dev/null +++ b/jsonw/jsonw.go @@ -0,0 +1,115 @@ +package jsonw + +import ( + "fmt" + "io" + "strconv" + "time" +) + +var nullLit = []byte(`null`) +var trueLit = []byte(`true`) +var falseLit = []byte(`false`) +var openBrace = []byte(`{`) +var closeBrace = []byte(`}`) +var openBracket = []byte(`[`) +var closeBracket = []byte(`]`) +var colon = []byte(`:`) +var comma = []byte(`,`) + +var Null = lit(nullLit) +var True = lit(trueLit) +var False = lit(falseLit) + +type Writer interface { + WriteJson(w io.Writer) +} + +type OrderedMap struct { + Keys []string + Values []Writer +} + +type writerFunc func(writer io.Writer) + +func (f writerFunc) WriteJson(w io.Writer) { + f(w) +} + +func NewOrderedMap(len int) *OrderedMap { + return &OrderedMap{ + Keys: make([]string, len), + Values: make([]Writer, len), + } +} + +func (m *OrderedMap) Add(key string, value Writer) { + m.Keys = append(m.Keys, key) + m.Values = append(m.Values, value) +} + +func (m *OrderedMap) WriteJson(writer io.Writer) { + writer.Write(openBrace) + for i, key := range m.Keys { + if i != 0 { + writer.Write(comma) + } + io.WriteString(writer, strconv.Quote(key)) + writer.Write(colon) + m.Values[i].WriteJson(writer) + } + writer.Write(closeBrace) +} + +type Array []Writer + +func (a Array) WriteJson(writer io.Writer) { + writer.Write(openBracket) + for i, val := range a { + if i != 0 { + writer.Write(comma) + } + val.WriteJson(writer) + } + writer.Write(closeBracket) +} + +func lit(b []byte) Writer { + return writerFunc(func(w io.Writer) { + w.Write(b) + }) +} + +func Int(i int) Writer { + return writerFunc(func(w io.Writer) { + io.WriteString(w, strconv.Itoa(i)) + }) +} + +func Float64(f float64) Writer { + return writerFunc(func(w io.Writer) { + io.WriteString(w, fmt.Sprintf("%f", f)) + }) +} + +func String(s string) Writer { + return writerFunc(func(w io.Writer) { + io.WriteString(w, strconv.Quote(s)) + }) +} + +func Bool(b bool) Writer { + return writerFunc(func(w io.Writer) { + if b { + w.Write(trueLit) + } else { + w.Write(falseLit) + } + }) +} + +func Time(t time.Time) Writer { + return writerFunc(func(w io.Writer) { + io.WriteString(w, t.Format(time.RFC3339)) + }) +} diff --git a/jsonw/jsonw_test.go b/jsonw/jsonw_test.go new file mode 100644 index 00000000000..512a04724b0 --- /dev/null +++ b/jsonw/jsonw_test.go @@ -0,0 +1,38 @@ +package jsonw + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestJsonWriter(t *testing.T) { + obj := &OrderedMap{} + obj.Add("test", Int(10)) + + obj.Add("array", &Array{ + Int(1), + String("2"), + Bool(true), + False, + Null, + Float64(1.3), + True, + }) + + obj.Add("emptyArray", &Array{}) + + child2 := &OrderedMap{} + child2.Add("child", Null) + + child1 := &OrderedMap{} + child1.Add("child", child2) + + obj.Add("child", child1) + + b := &bytes.Buffer{} + obj.WriteJson(b) + + require.Equal(t, `{"test":10,"array":[1,"2",true,false,null,1.300000,true],"emptyArray":[],"child":{"child":{"child":null}}}`, b.String()) +} diff --git a/jsonw/output.go b/jsonw/output.go deleted file mode 100644 index e53a4a3c0df..00000000000 --- a/jsonw/output.go +++ /dev/null @@ -1,126 +0,0 @@ -package jsonw - -import ( - "fmt" - "io" - "strconv" - "time" -) - -var nullLit = []byte(`null`) -var trueLit = []byte(`true`) -var falseLit = []byte(`false`) -var openBrace = []byte(`{`) -var closeBrace = []byte(`}`) -var openBracket = []byte(`[`) -var closeBracket = []byte(`]`) -var colon = []byte(`:`) -var comma = []byte(`,`) -var NullWriter = &litWriter{nullLit} - -type Writer struct { - out io.Writer - first bool -} - -type JsonWriter interface { - WriteJson(w *Writer) -} - -func New(w io.Writer) *Writer { - return &Writer{ - out: w, - first: true, - } -} - -func (w *Writer) split() { - if !w.first { - w.out.Write(comma) - } - w.first = false -} - -func (w *Writer) Null() { - w.split() - w.out.Write(nullLit) -} - -func (w *Writer) Bool(v bool) { - w.split() - if v { - w.out.Write(trueLit) - } else { - w.out.Write(falseLit) - } -} - -func (w *Writer) True() { - w.split() - w.out.Write(trueLit) -} - -func (w *Writer) False() { - w.split() - w.out.Write(falseLit) -} - -func (w *Writer) Int(v int) { - w.split() - io.WriteString(w.out, fmt.Sprintf("%d", v)) -} - -func (w *Writer) Float64(v float64) { - w.split() - io.WriteString(w.out, fmt.Sprintf("%f", v)) -} - -func (w *Writer) String(v string) { - w.split() - io.WriteString(w.out, strconv.Quote(v)) -} - -func (w *Writer) Time(t time.Time) { - w.split() - io.WriteString(w.out, strconv.Quote(t.Format(time.RFC3339))) -} - -func (w *Writer) BeginObject() { - w.split() - - w.first = true - w.out.Write(openBrace) -} - -func (w *Writer) ObjectKey(key string) { - w.split() - w.first = true - - io.WriteString(w.out, strconv.Quote(key)) - w.out.Write(colon) -} - -func (w *Writer) EndObject() { - w.first = false - w.out.Write(closeBrace) -} - -func (w *Writer) BeginArray() { - w.split() - - w.first = true - w.out.Write(openBracket) -} - -func (w *Writer) EndArray() { - w.first = false - w.out.Write(closeBracket) -} - -type litWriter struct { - val []byte -} - -func (l *litWriter) WriteJson(writer *Writer) { - writer.Null() -} diff --git a/jsonw/output_test.go b/jsonw/output_test.go deleted file mode 100644 index 5cb1eb0d357..00000000000 --- a/jsonw/output_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package jsonw - -import ( - "bytes" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestJsonWriter(t *testing.T) { - b := &bytes.Buffer{} - w := New(b) - w.BeginObject() - w.ObjectKey("test") - w.Int(10) - w.ObjectKey("array") - w.BeginArray() - w.Int(1) - w.String("2") - w.True() - w.False() - w.Null() - w.Float64(1.3) - w.Bool(true) - w.EndArray() - w.ObjectKey("emptyArray") - - w.BeginArray() - w.EndArray() - - w.ObjectKey("child") - w.BeginObject() - w.ObjectKey("child") - - w.BeginObject() - w.ObjectKey("child") - w.Null() - w.EndObject() - - w.EndObject() - - w.EndObject() - - require.Equal(t, `{"test":10,"array":[1,"2",true,false,null,1.300000,true],"emptyArray":[],"child":{"child":{"child":null}}}`, b.String()) -} diff --git a/neelance/errors/errors.go b/neelance/errors/errors.go index 6af1bfe472e..754d8578827 100644 --- a/neelance/errors/errors.go +++ b/neelance/errors/errors.go @@ -2,7 +2,6 @@ package errors import ( "fmt" - "io" "github.com/vektah/gqlgen/jsonw" ) @@ -55,37 +54,32 @@ func (c *Builder) Error(err error) { c.Errors = append(c.Errors, Errorf("%s", err.Error())) } -func WriteErrors(b io.Writer, errs []*QueryError) { - w := jsonw.New(b) - w.BeginArray() +func ErrorWriter(errs []*QueryError) jsonw.Writer { + res := jsonw.Array{} + for _, err := range errs { if err == nil { - w.Null() + res = append(res, jsonw.Null) continue } - w.BeginObject() - w.ObjectKey("message") - w.String(err.Message) + errObj := &jsonw.OrderedMap{} + + errObj.Add("message", jsonw.String(err.Message)) if len(err.Locations) > 0 { - w.ObjectKey("locations") - w.BeginArray() + locations := jsonw.Array{} for _, location := range err.Locations { - w.BeginObject() - - w.ObjectKey("line") - w.Int(location.Line) - - w.ObjectKey("column") - w.Int(location.Column) + locationObj := &jsonw.OrderedMap{} + locationObj.Add("line", jsonw.Int(location.Line)) + locationObj.Add("column", jsonw.Int(location.Column)) - w.EndObject() + locations = append(locations, locationObj) } - w.EndArray() - } - w.EndObject() + errObj.Add("locations", locations) + } } - w.EndArray() + + return res } diff --git a/templates/file.gotpl b/templates/file.gotpl index a53749eb14b..60dc1dcc781 100644 --- a/templates/file.gotpl +++ b/templates/file.gotpl @@ -41,12 +41,12 @@ func NewExecutor(resolvers Resolvers) func(context.Context, string, string, map[ ctx: ctx, } - var result jsonw.JsonWriter + var data jsonw.Writer if op.Type == query.Query { - result = c._{{.QueryRoot|lcFirst}}(op.Selections, nil) + data = c._{{.QueryRoot|lcFirst}}(op.Selections, nil) {{- if .MutationRoot}} } else if op.Type == query.Mutation { - result = c._{{.MutationRoot|lcFirst}}(op.Selections, nil) + data = c._{{.MutationRoot|lcFirst}}(op.Selections, nil) {{- end}} } else { return []*errors.QueryError{errors.Errorf("unsupported operation type")} @@ -54,18 +54,14 @@ func NewExecutor(resolvers Resolvers) func(context.Context, string, string, map[ c.wg.Wait() - writer := jsonw.New(w) - writer.BeginObject() - - writer.ObjectKey("data") - result.WriteJson(writer) + result := &jsonw.OrderedMap{} + result.Add("data", data) if len(c.Errors) > 0 { - writer.ObjectKey("errors") - errors.WriteErrors(w, c.Errors) + result.Add("errors", errors.ErrorWriter(c.Errors)) } - writer.EndObject() + result.WriteJson(w) return nil } } diff --git a/templates/interface.gotpl b/templates/interface.gotpl index 0b745fdc3ad..0e2f98a98e9 100644 --- a/templates/interface.gotpl +++ b/templates/interface.gotpl @@ -1,10 +1,10 @@ {{- define "interface"}} {{- $interface := . }} -func (ec *executionContext) _{{$interface.Type.GraphQLName|lcFirst}}(sel []query.Selection, it {{$interface.Type.Local}}) jsonw.JsonWriter { - switch it := it.(type) { +func (ec *executionContext) _{{$interface.Type.GraphQLName|lcFirst}}(sel []query.Selection, it *{{$interface.Type.Local}}) jsonw.Writer { + switch it := (*it).(type) { case nil: - return jsonw.NullWriter + return jsonw.Null {{- range $implementor := $interface.Type.Implementors }} case {{$implementor.Local}}: return ec._{{$implementor.GraphQLName|lcFirst}}(sel, &it) diff --git a/templates/object.gotpl b/templates/object.gotpl index 4b3e455089f..b7eb5459f22 100644 --- a/templates/object.gotpl +++ b/templates/object.gotpl @@ -1,26 +1,16 @@ {{- define "object" }} {{ $object := . }} -type _{{ .Type.GraphQLName}}Node struct { - _fields []collectedField - - {{- range $field := .Fields }} - {{- if $field.Type.Scalar }} - {{$field.GraphQLName|ucFirst}} {{ $field.Type.Local }} - {{- else }} - {{$field.GraphQLName|ucFirst}} {{if $field.Type.IsSlice}}[]{{end}}jsonw.JsonWriter - {{- end }} - {{- end}} -} var {{ $object.Type.GraphQLName|lcFirst}}Implementors = {{$object.Implementors}} // nolint: gocyclo, errcheck, gas, goconst -func (ec *executionContext) _{{$object.Type.GraphQLName|lcFirst}}(sel []query.Selection, it *{{$object.Type.Local}}) jsonw.JsonWriter { - node := _{{$object.Type.GraphQLName}}Node { - _fields: ec.collectFields(sel, {{$object.Type.GraphQLName|lcFirst}}Implementors, map[string]bool{}), - } +func (ec *executionContext) _{{$object.Type.GraphQLName|lcFirst}}(sel []query.Selection, it *{{$object.Type.Local}}) jsonw.Writer { + fields := ec.collectFields(sel, {{$object.Type.GraphQLName|lcFirst}}Implementors, map[string]bool{}) + out := jsonw.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + out.Values[i] = jsonw.Null - for _, field := range node._fields { switch field.Name { {{- range $field := $object.Fields }} case "{{$field.GraphQLName}}": @@ -28,7 +18,7 @@ func (ec *executionContext) _{{$object.Type.GraphQLName|lcFirst}}(sel []query.Se {{- if $field.IsResolver }} ec.wg.Add(1) - go func(field collectedField) { + go func(i int, field collectedField) { defer ec.wg.Done() {{- end }} @@ -52,26 +42,10 @@ func (ec *executionContext) _{{$object.Type.GraphQLName|lcFirst}}(sel []query.Se } {{- end }} - {{- if $field.Type.Scalar }} - node.{{$field.GraphQLName|ucFirst}} = res - {{- else }} - {{- if or $field.Type.IsPtr $field.Type.IsSlice }} - if res != nil { - {{- end }} - {{- if $field.Type.IsSlice }} - for i := range {{$field.Type.ByVal "res" }} { - node.{{$field.GraphQLName|ucFirst}} = append(node.{{$field.GraphQLName|ucFirst}}, ec._{{$field.Type.GraphQLName|lcFirst}}(field.Selections, {{ $field.Type.Elem.ByRef "res[i]" }})) - } - {{- else }} - node.{{$field.GraphQLName|ucFirst}} = ec._{{$field.Type.GraphQLName|lcFirst}}(field.Selections, {{$field.Type.ByRef "res" }}) - {{- end }} - {{- if or $field.Type.IsPtr $field.Type.IsSlice }} - } - {{- end}} - {{- end }} + {{ $field.WriteJson "out.Values[i]" }} {{- if $field.IsResolver }} - }(field) + }(i, field) {{- end }} {{- end }} default: @@ -79,21 +53,8 @@ func (ec *executionContext) _{{$object.Type.GraphQLName|lcFirst}}(sel []query.Se } } - return &node + return out } -func (t *_{{ $object.Type.GraphQLName }}Node) WriteJson(w *jsonw.Writer) { - w.BeginObject() - for _, field := range t._fields { - switch field.Name { - {{- range $field := $object.Fields }} - case "{{$field.GraphQLName}}": - w.ObjectKey({{$field.GraphQLName|quote}}) - {{ $field.WriteJson }} - {{- end }} - } - } - w.EndObject() -} {{- end}} diff --git a/types.go b/types.go index 80ff6f1e1c8..732203d1933 100644 --- a/types.go +++ b/types.go @@ -1,9 +1,11 @@ package main import ( + "bytes" "fmt" "strconv" "strings" + "text/template" ) type kind struct { @@ -123,40 +125,60 @@ func (f *Field) CallArgs(object object) string { return strings.Join(args, ", ") } -// should be in the template, but its recursive and has a bunch fo args -func (f *Field) WriteJson() string { - return f.doWriteJson("t."+ucFirst(f.GraphQLName), f.Type.Modifiers, false) +// should be in the template, but its recursive and has a bunch of args +func (f *Field) WriteJson(res string) string { + return f.doWriteJson(res, "res", f.Type.Modifiers, false, 1) } -func (f *Field) doWriteJson(val string, remainingMods []string, isPtr bool) string { +func (f *Field) doWriteJson(res string, val string, remainingMods []string, isPtr bool, depth int) string { switch { case len(remainingMods) > 0 && remainingMods[0] == modPtr: - return fmt.Sprintf( - "if %s == nil { w.Null() } else { %s } ", - val, f.doWriteJson(val, remainingMods[1:], true), - ) + return tpl(` + if {{.val}} == nil { + {{.res}} = jsonw.Null + } else { + {{.next}} + }`, map[string]interface{}{ + "res": res, + "val": val, + "next": f.doWriteJson(res, val, remainingMods[1:], true, depth+1), + }) case len(remainingMods) > 0 && remainingMods[0] == modList: if isPtr { val = "*" + val } - - return strings.Join([]string{ - "w.BeginArray()", - fmt.Sprintf("for _, val := range %s {", val), - f.doWriteJson("val", remainingMods[1:], false), - "}", - "w.EndArray()", - }, "\n") + var tmp = "tmp" + strconv.Itoa(depth) + var arr = "arr" + strconv.Itoa(depth) + var loopval = "loopval" + strconv.Itoa(depth) + + return tpl(` + {{.arr}} := jsonw.Array{} + for _, {{.loopval}} := range {{.val}} { + var {{.tmp}} jsonw.Writer + {{.next}} + {{.arr}} = append({{.arr}}, {{.tmp}}) + } + {{.res}} = {{.arr}}`, map[string]interface{}{ + "res": res, + "val": val, + "tmp": tmp, + "arr": arr, + "loopval": loopval, + "next": f.doWriteJson(tmp, loopval, remainingMods[1:], false, depth+1), + }) case f.Type.Scalar: if isPtr { val = "*" + val } - return fmt.Sprintf("w.%s(%s)", ucFirst(f.Type.Name), val) + return fmt.Sprintf("%s = jsonw.%s(%s)", res, ucFirst(f.Type.Name), val) default: - return fmt.Sprintf("%s.WriteJson(w)", val) + if !isPtr { + val = "&" + val + } + return fmt.Sprintf("%s = ec._%s(field.Selections, %s)", res, lcFirst(f.Type.GraphQLName), val) } } @@ -190,3 +212,9 @@ type FieldArgument struct { Name string Type kind } + +func tpl(tpl string, vars map[string]interface{}) string { + b := &bytes.Buffer{} + template.Must(template.New("inline").Parse(tpl)).Execute(b, vars) + return b.String() +}