Add support for binding with a custom marshal/unmarshal function (#104)
## Summary: This is useful if you want to bind to a type you don't control (or use for other things) but need different serialization than its default. This is a feature gqlgen has and we've found it very useful. For example, in webapp we want to bind `DateTime` to `time.Time`, but its default serialization is not compatible with Python, so currently we have to bind to a wrapper type and cast all over the place, which is exactly the sort of boilerplate genqlient is supposed to avoid. For unmarshaling, the implementation basically just follows the existing support for abstract types; instead of calling our own generated helper, we now call your specified function. This required some refactoring to abstract the handling of custom unmarshalers generally from abstract types specifically, and to wire in not only the unmarshaler-name but also the `generator` (in order to compute the right import alias). For marshaling, I had to implement all that stuff over again; it's mostly parallel to unmarshaling (and I made a few minor changes to unmarshaling to make the two more parallel). Luckily, after #103 I at least only had to do it once, rather than implementing the same functionality for arguments and for input-type fields. It was still quite a bit of code; I didn't try to be quite as completionist about the tests as with unmarshal but still had to add a few. Issue: https://github.com/Khan/genqlient/issues/38 ## Test plan: make check Author: benjaminjkraft Reviewers: StevenACoffman, dnerdy, benjaminjkraft, aberkan, jvoll, mahtabsabet, MiguelCastillo Required Reviewers: Approved By: StevenACoffman, dnerdy Checks: ✅ Test (1.17), ✅ Test (1.16), ✅ Test (1.15), ✅ Test (1.14), ✅ Lint, ✅ Test (1.17), ✅ Test (1.16), ✅ Test (1.15), ✅ Test (1.14), ✅ Lint Pull Request URL: https://github.com/Khan/genqlient/pull/104
This commit is contained in:
@@ -44,6 +44,8 @@ type Config struct {
|
||||
type TypeBinding struct {
|
||||
Type string `yaml:"type"`
|
||||
ExpectExactFields string `yaml:"expect_exact_fields"`
|
||||
Marshaler string `yaml:"marshaler"`
|
||||
Unmarshaler string `yaml:"unmarshaler"`
|
||||
}
|
||||
|
||||
// ValidateAndFillDefaults ensures that the configuration is valid, and fills
|
||||
|
||||
+16
-3
@@ -125,6 +125,7 @@ func (g *generator) convertOperation(
|
||||
},
|
||||
Fields: fields,
|
||||
Selection: operation.SelectionSet,
|
||||
Generator: g,
|
||||
}
|
||||
|
||||
return g.addType(goType, goType.GoName, operation.Position)
|
||||
@@ -188,6 +189,7 @@ func (g *generator) convertArguments(
|
||||
// fake name, used by addType
|
||||
GraphQLName: name,
|
||||
},
|
||||
Generator: g,
|
||||
}
|
||||
goTypAgain, err := g.addType(goTyp, goTyp.GoName, operation.Position)
|
||||
if err != nil {
|
||||
@@ -217,7 +219,9 @@ func (g *generator) convertType(
|
||||
localBinding := options.Bind
|
||||
if localBinding != "" && localBinding != "-" {
|
||||
goRef, err := g.ref(localBinding)
|
||||
return &goOpaqueType{goRef, typ.Name()}, err
|
||||
// TODO(benkraft): Add syntax to specify a custom (un)marshaler, if
|
||||
// it proves useful.
|
||||
return &goOpaqueType{GoRef: goRef, GraphQLName: typ.Name()}, err
|
||||
}
|
||||
|
||||
if typ.Elem != nil {
|
||||
@@ -269,11 +273,16 @@ func (g *generator) convertDefinition(
|
||||
}
|
||||
}
|
||||
goRef, err := g.ref(globalBinding.Type)
|
||||
return &goOpaqueType{goRef, def.Name}, err
|
||||
return &goOpaqueType{
|
||||
GoRef: goRef,
|
||||
GraphQLName: def.Name,
|
||||
Marshaler: globalBinding.Marshaler,
|
||||
Unmarshaler: globalBinding.Unmarshaler,
|
||||
}, err
|
||||
}
|
||||
goBuiltinName, ok := builtinTypes[def.Name]
|
||||
if ok {
|
||||
return &goOpaqueType{goBuiltinName, def.Name}, nil
|
||||
return &goOpaqueType{GoRef: goBuiltinName, GraphQLName: def.Name}, nil
|
||||
}
|
||||
|
||||
// Determine the name to use for this type.
|
||||
@@ -337,6 +346,7 @@ func (g *generator) convertDefinition(
|
||||
Fields: fields,
|
||||
Selection: selectionSet,
|
||||
descriptionInfo: desc,
|
||||
Generator: g,
|
||||
}
|
||||
return g.addType(goType, goType.GoName, pos)
|
||||
|
||||
@@ -346,6 +356,7 @@ func (g *generator) convertDefinition(
|
||||
Fields: make([]*goStructField, len(def.Fields)),
|
||||
descriptionInfo: desc,
|
||||
IsInput: true,
|
||||
Generator: g,
|
||||
}
|
||||
// To handle recursive types, we need to add the type to the type-map
|
||||
// *before* converting its fields.
|
||||
@@ -700,6 +711,7 @@ func (g *generator) convertNamedFragment(fragment *ast.FragmentDefinition) (goTy
|
||||
Fields: fields,
|
||||
Selection: fragment.SelectionSet,
|
||||
descriptionInfo: desc,
|
||||
Generator: g,
|
||||
}
|
||||
g.typeMap[fragment.Name] = goType
|
||||
return goType, nil
|
||||
@@ -729,6 +741,7 @@ func (g *generator) convertNamedFragment(fragment *ast.FragmentDefinition) (goTy
|
||||
Fields: implFields,
|
||||
Selection: fragment.SelectionSet,
|
||||
descriptionInfo: implDesc,
|
||||
Generator: g,
|
||||
}
|
||||
goType.Implementations[i] = implTyp
|
||||
g.typeMap[implTyp.GoName] = implTyp
|
||||
|
||||
@@ -83,8 +83,13 @@ func TestGenerate(t *testing.T) {
|
||||
ExportOperations: queriesFilename,
|
||||
ContextType: "-",
|
||||
Bindings: map[string]*TypeBinding{
|
||||
"ID": {Type: "github.com/Khan/genqlient/internal/testutil.ID"},
|
||||
"DateTime": {Type: "time.Time"},
|
||||
"ID": {Type: "github.com/Khan/genqlient/internal/testutil.ID"},
|
||||
"DateTime": {Type: "time.Time"},
|
||||
"Date": {
|
||||
Type: "time.Time",
|
||||
Marshaler: "github.com/Khan/genqlient/internal/testutil.MarshalDate",
|
||||
Unmarshaler: "github.com/Khan/genqlient/internal/testutil.UnmarshalDate",
|
||||
},
|
||||
"Junk": {Type: "interface{}"},
|
||||
"ComplexJunk": {Type: "[]map[string]*[]*map[string]interface{}"},
|
||||
"Pokemon": {
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
{{/* See unmarshal.go.tmpl for more on how this works; this is mostly just
|
||||
parallel (and simplified -- we don't need to handle embedding). */}}
|
||||
|
||||
func (v *{{.GoName}}) MarshalJSON() ([]byte, error) {
|
||||
{{/* We do the two passes in the opposite order of unmarshal: first, we
|
||||
marshal the special fields, then we assign those to the wrapper struct
|
||||
and finish marshaling the whole object. But first we set up the
|
||||
object for the second part, so we can assign to it as we go. */}}
|
||||
var fullObject struct{
|
||||
*{{.GoName}}
|
||||
{{range .Fields -}}
|
||||
{{if .NeedsMarshaler -}}
|
||||
{{.GoName}} {{repeat .GoType.SliceDepth "[]"}}{{ref "encoding/json.RawMessage"}} `json:"{{.JSONName}}"`
|
||||
{{end -}}
|
||||
{{end -}}
|
||||
{{ref "github.com/Khan/genqlient/graphql.NoMarshalJSON"}}
|
||||
}
|
||||
fullObject.{{.GoName}} = v
|
||||
|
||||
{{range $field := .Fields -}}
|
||||
{{if $field.NeedsMarshaler -}}
|
||||
{
|
||||
{{/* Here dst is the json.RawMessage, and src is the Go type */}}
|
||||
dst := &fullObject.{{$field.GoName}}
|
||||
src := v.{{$field.GoName}}
|
||||
{{range $i := intRange $field.GoType.SliceDepth -}}
|
||||
*dst = make(
|
||||
{{repeat (sub $field.GoType.SliceDepth $i) "[]"}}{{ref "encoding/json.RawMessage"}},
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
{{end -}}
|
||||
var err error
|
||||
*dst, err = {{$field.Marshaler $.Generator}}(
|
||||
{{/* src is a pointer to the struct-field (or field-element, etc.).
|
||||
We want to pass a pointer to the type you specified, so if
|
||||
there's a pointer on the field that's exactly what we want,
|
||||
and if not we need to take the address. */ -}}
|
||||
{{if not $field.GoType.IsPointer}}&{{end}}src)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Unable to marshal {{$.GoName}}.{{$field.GoName}}: %w", err)
|
||||
}
|
||||
{{range $i := intRange $field.GoType.SliceDepth -}}
|
||||
}
|
||||
{{end -}}
|
||||
}
|
||||
{{end -}}
|
||||
{{end}}
|
||||
|
||||
return {{ref "encoding/json.Marshal"}}(&fullObject)
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
query CustomMarshal($date: Date!) {
|
||||
usersBornOn(date: $date) {
|
||||
id
|
||||
birthdate
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
query CustomMarshalSlice(
|
||||
$datesss: [[[Date!]!]!]!,
|
||||
# @genqlient(pointer: true)
|
||||
$datesssp: [[[Date!]!]!]!,
|
||||
) {
|
||||
acceptsListOfListOfListsOfDates(datesss: $datesss)
|
||||
withPointer: acceptsListOfListOfListsOfDates(datesss: $datesssp)
|
||||
}
|
||||
+7
@@ -3,6 +3,7 @@
|
||||
We don't really have anything useful to do with this description though.
|
||||
"""
|
||||
scalar DateTime
|
||||
scalar Date
|
||||
scalar Junk
|
||||
scalar ComplexJunk
|
||||
|
||||
@@ -44,6 +45,7 @@ input UserQueryInput {
|
||||
role: Role
|
||||
names: [String]
|
||||
hasPokemon: PokemonInput
|
||||
birthdate: Date
|
||||
}
|
||||
|
||||
type AuthMethod {
|
||||
@@ -66,6 +68,7 @@ type User {
|
||||
authMethods: [AuthMethod!]!
|
||||
pokemon: [Pokemon!]
|
||||
greeting: Clip
|
||||
birthdate: Date
|
||||
}
|
||||
|
||||
"""An audio clip, such as of a user saying hello."""
|
||||
@@ -153,6 +156,9 @@ type Query {
|
||||
|
||||
"""usersWithRole looks a user up by role."""
|
||||
usersWithRole(role: Role!): [User!]!
|
||||
|
||||
usersBornOn(date: Date!): [User!]!
|
||||
|
||||
root: Topic!
|
||||
randomItem: Content!
|
||||
randomLeaf: LeafContent!
|
||||
@@ -163,6 +169,7 @@ type Query {
|
||||
listOfListsOfLists: [[[String!]!]!]!
|
||||
listOfListsOfListsOfContent: [[[Content!]!]!]!
|
||||
recur(input: RecursiveInput!): Recursive
|
||||
acceptsListOfListOfListsOfDates(datesss: [[[Date!]!]!]!): Boolean
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
|
||||
+74
-62
@@ -55,15 +55,15 @@ func (v *ComplexInlineFragmentsConflictingStuffTopic) implementsGraphQLInterface
|
||||
// GetTypename is a part of, and documented with, the interface ComplexInlineFragmentsConflictingStuffContent.
|
||||
func (v *ComplexInlineFragmentsConflictingStuffTopic) GetTypename() string { return v.Typename }
|
||||
|
||||
func __unmarshalComplexInlineFragmentsConflictingStuffContent(v *ComplexInlineFragmentsConflictingStuffContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalComplexInlineFragmentsConflictingStuffContent(b []byte, v *ComplexInlineFragmentsConflictingStuffContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -71,13 +71,13 @@ func __unmarshalComplexInlineFragmentsConflictingStuffContent(v *ComplexInlineFr
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(ComplexInlineFragmentsConflictingStuffArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(ComplexInlineFragmentsConflictingStuffVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(ComplexInlineFragmentsConflictingStuffTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -142,15 +142,15 @@ func (v *ComplexInlineFragmentsNestedStuffTopic) implementsGraphQLInterfaceCompl
|
||||
// GetTypename is a part of, and documented with, the interface ComplexInlineFragmentsNestedStuffContent.
|
||||
func (v *ComplexInlineFragmentsNestedStuffTopic) GetTypename() string { return v.Typename }
|
||||
|
||||
func __unmarshalComplexInlineFragmentsNestedStuffContent(v *ComplexInlineFragmentsNestedStuffContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalComplexInlineFragmentsNestedStuffContent(b []byte, v *ComplexInlineFragmentsNestedStuffContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -158,13 +158,13 @@ func __unmarshalComplexInlineFragmentsNestedStuffContent(v *ComplexInlineFragmen
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(ComplexInlineFragmentsNestedStuffArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(ComplexInlineFragmentsNestedStuffVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(ComplexInlineFragmentsNestedStuffTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -182,6 +182,10 @@ type ComplexInlineFragmentsNestedStuffTopic struct {
|
||||
|
||||
func (v *ComplexInlineFragmentsNestedStuffTopic) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*ComplexInlineFragmentsNestedStuffTopic
|
||||
Children []json.RawMessage `json:"children"`
|
||||
@@ -195,15 +199,15 @@ func (v *ComplexInlineFragmentsNestedStuffTopic) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.Children
|
||||
raw := firstPass.Children
|
||||
*target = make(
|
||||
dst := &v.Children
|
||||
src := firstPass.Children
|
||||
*dst = make(
|
||||
[]ComplexInlineFragmentsNestedStuffTopicChildrenContent,
|
||||
len(raw))
|
||||
for i, raw := range raw {
|
||||
target := &(*target)[i]
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
err = __unmarshalComplexInlineFragmentsNestedStuffTopicChildrenContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal ComplexInlineFragmentsNestedStuffTopic.Children: %w", err)
|
||||
@@ -229,6 +233,10 @@ type ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTop
|
||||
|
||||
func (v *ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopic) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopic
|
||||
Children []json.RawMessage `json:"children"`
|
||||
@@ -242,15 +250,15 @@ func (v *ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParen
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.Children
|
||||
raw := firstPass.Children
|
||||
*target = make(
|
||||
dst := &v.Children
|
||||
src := firstPass.Children
|
||||
*dst = make(
|
||||
[]ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopicChildrenContent,
|
||||
len(raw))
|
||||
for i, raw := range raw {
|
||||
target := &(*target)[i]
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
err = __unmarshalComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopicChildrenContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopic.Children: %w", err)
|
||||
@@ -344,15 +352,15 @@ func (v *ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParen
|
||||
return v.Name
|
||||
}
|
||||
|
||||
func __unmarshalComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopicChildrenContent(v *ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopicChildrenContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopicChildrenContent(b []byte, v *ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopicChildrenContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -360,13 +368,13 @@ func __unmarshalComplexInlineFragmentsNestedStuffTopicChildrenArticleParentConte
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopicChildrenArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopicChildrenVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopicChildrenTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -447,15 +455,15 @@ func (v *ComplexInlineFragmentsNestedStuffTopicChildrenTopic) GetTypename() stri
|
||||
// GetId is a part of, and documented with, the interface ComplexInlineFragmentsNestedStuffTopicChildrenContent.
|
||||
func (v *ComplexInlineFragmentsNestedStuffTopicChildrenTopic) GetId() testutil.ID { return v.Id }
|
||||
|
||||
func __unmarshalComplexInlineFragmentsNestedStuffTopicChildrenContent(v *ComplexInlineFragmentsNestedStuffTopicChildrenContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalComplexInlineFragmentsNestedStuffTopicChildrenContent(b []byte, v *ComplexInlineFragmentsNestedStuffTopicChildrenContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -463,13 +471,13 @@ func __unmarshalComplexInlineFragmentsNestedStuffTopicChildrenContent(v *Complex
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(ComplexInlineFragmentsNestedStuffTopicChildrenArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(ComplexInlineFragmentsNestedStuffTopicChildrenVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(ComplexInlineFragmentsNestedStuffTopicChildrenTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -565,15 +573,15 @@ func (v *ComplexInlineFragmentsRandomItemTopic) GetId() testutil.ID { return v.I
|
||||
// GetName is a part of, and documented with, the interface ComplexInlineFragmentsRandomItemContent.
|
||||
func (v *ComplexInlineFragmentsRandomItemTopic) GetName() string { return v.Name }
|
||||
|
||||
func __unmarshalComplexInlineFragmentsRandomItemContent(v *ComplexInlineFragmentsRandomItemContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalComplexInlineFragmentsRandomItemContent(b []byte, v *ComplexInlineFragmentsRandomItemContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -581,13 +589,13 @@ func __unmarshalComplexInlineFragmentsRandomItemContent(v *ComplexInlineFragment
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(ComplexInlineFragmentsRandomItemArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(ComplexInlineFragmentsRandomItemVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(ComplexInlineFragmentsRandomItemTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -721,15 +729,15 @@ func (v *ComplexInlineFragmentsRepeatedStuffTopic) GetName() string { return v.N
|
||||
// GetOtherName is a part of, and documented with, the interface ComplexInlineFragmentsRepeatedStuffContent.
|
||||
func (v *ComplexInlineFragmentsRepeatedStuffTopic) GetOtherName() string { return v.OtherName }
|
||||
|
||||
func __unmarshalComplexInlineFragmentsRepeatedStuffContent(v *ComplexInlineFragmentsRepeatedStuffContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalComplexInlineFragmentsRepeatedStuffContent(b []byte, v *ComplexInlineFragmentsRepeatedStuffContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -737,13 +745,13 @@ func __unmarshalComplexInlineFragmentsRepeatedStuffContent(v *ComplexInlineFragm
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(ComplexInlineFragmentsRepeatedStuffArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(ComplexInlineFragmentsRepeatedStuffVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(ComplexInlineFragmentsRepeatedStuffTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -789,6 +797,10 @@ type ComplexInlineFragmentsResponse struct {
|
||||
|
||||
func (v *ComplexInlineFragmentsResponse) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*ComplexInlineFragmentsResponse
|
||||
RandomItem json.RawMessage `json:"randomItem"`
|
||||
@@ -805,10 +817,10 @@ func (v *ComplexInlineFragmentsResponse) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.RandomItem
|
||||
raw := firstPass.RandomItem
|
||||
dst := &v.RandomItem
|
||||
src := firstPass.RandomItem
|
||||
err = __unmarshalComplexInlineFragmentsRandomItemContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal ComplexInlineFragmentsResponse.RandomItem: %w", err)
|
||||
@@ -816,10 +828,10 @@ func (v *ComplexInlineFragmentsResponse) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.RepeatedStuff
|
||||
raw := firstPass.RepeatedStuff
|
||||
dst := &v.RepeatedStuff
|
||||
src := firstPass.RepeatedStuff
|
||||
err = __unmarshalComplexInlineFragmentsRepeatedStuffContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal ComplexInlineFragmentsResponse.RepeatedStuff: %w", err)
|
||||
@@ -827,10 +839,10 @@ func (v *ComplexInlineFragmentsResponse) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.ConflictingStuff
|
||||
raw := firstPass.ConflictingStuff
|
||||
dst := &v.ConflictingStuff
|
||||
src := firstPass.ConflictingStuff
|
||||
err = __unmarshalComplexInlineFragmentsConflictingStuffContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal ComplexInlineFragmentsResponse.ConflictingStuff: %w", err)
|
||||
@@ -838,10 +850,10 @@ func (v *ComplexInlineFragmentsResponse) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.NestedStuff
|
||||
raw := firstPass.NestedStuff
|
||||
dst := &v.NestedStuff
|
||||
src := firstPass.NestedStuff
|
||||
err = __unmarshalComplexInlineFragmentsNestedStuffContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal ComplexInlineFragmentsResponse.NestedStuff: %w", err)
|
||||
|
||||
+96
-44
@@ -17,6 +17,10 @@ type ComplexNamedFragmentsResponse struct {
|
||||
|
||||
func (v *ComplexNamedFragmentsResponse) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*ComplexNamedFragmentsResponse
|
||||
graphql.NoUnmarshalJSON
|
||||
@@ -77,15 +81,15 @@ func (v *ContentFieldsTopic) GetName() string { return v.Name }
|
||||
// GetUrl is a part of, and documented with, the interface ContentFields.
|
||||
func (v *ContentFieldsTopic) GetUrl() string { return v.Url }
|
||||
|
||||
func __unmarshalContentFields(v *ContentFields, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalContentFields(b []byte, v *ContentFields) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -93,13 +97,13 @@ func __unmarshalContentFields(v *ContentFields, m json.RawMessage) error {
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(ContentFieldsArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(ContentFieldsVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(ContentFieldsTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -148,6 +152,10 @@ type InnerQueryFragment struct {
|
||||
|
||||
func (v *InnerQueryFragment) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*InnerQueryFragment
|
||||
RandomItem json.RawMessage `json:"randomItem"`
|
||||
@@ -163,10 +171,10 @@ func (v *InnerQueryFragment) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.RandomItem
|
||||
raw := firstPass.RandomItem
|
||||
dst := &v.RandomItem
|
||||
src := firstPass.RandomItem
|
||||
err = __unmarshalInnerQueryFragmentRandomItemContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal InnerQueryFragment.RandomItem: %w", err)
|
||||
@@ -174,10 +182,10 @@ func (v *InnerQueryFragment) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.RandomLeaf
|
||||
raw := firstPass.RandomLeaf
|
||||
dst := &v.RandomLeaf
|
||||
src := firstPass.RandomLeaf
|
||||
err = __unmarshalInnerQueryFragmentRandomLeafLeafContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal InnerQueryFragment.RandomLeaf: %w", err)
|
||||
@@ -185,10 +193,10 @@ func (v *InnerQueryFragment) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.OtherLeaf
|
||||
raw := firstPass.OtherLeaf
|
||||
dst := &v.OtherLeaf
|
||||
src := firstPass.OtherLeaf
|
||||
err = __unmarshalInnerQueryFragmentOtherLeafLeafContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal InnerQueryFragment.OtherLeaf: %w", err)
|
||||
@@ -205,6 +213,10 @@ type InnerQueryFragmentOtherLeafArticle struct {
|
||||
|
||||
func (v *InnerQueryFragmentOtherLeafArticle) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*InnerQueryFragmentOtherLeafArticle
|
||||
graphql.NoUnmarshalJSON
|
||||
@@ -250,15 +262,15 @@ func (v *InnerQueryFragmentOtherLeafVideo) implementsGraphQLInterfaceInnerQueryF
|
||||
// GetTypename is a part of, and documented with, the interface InnerQueryFragmentOtherLeafLeafContent.
|
||||
func (v *InnerQueryFragmentOtherLeafVideo) GetTypename() string { return v.Typename }
|
||||
|
||||
func __unmarshalInnerQueryFragmentOtherLeafLeafContent(v *InnerQueryFragmentOtherLeafLeafContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalInnerQueryFragmentOtherLeafLeafContent(b []byte, v *InnerQueryFragmentOtherLeafLeafContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -266,10 +278,10 @@ func __unmarshalInnerQueryFragmentOtherLeafLeafContent(v *InnerQueryFragmentOthe
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(InnerQueryFragmentOtherLeafArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(InnerQueryFragmentOtherLeafVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing LeafContent.__typename")
|
||||
@@ -288,6 +300,10 @@ type InnerQueryFragmentOtherLeafVideo struct {
|
||||
|
||||
func (v *InnerQueryFragmentOtherLeafVideo) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*InnerQueryFragmentOtherLeafVideo
|
||||
graphql.NoUnmarshalJSON
|
||||
@@ -323,6 +339,10 @@ type InnerQueryFragmentRandomItemArticle struct {
|
||||
|
||||
func (v *InnerQueryFragmentRandomItemArticle) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*InnerQueryFragmentRandomItemArticle
|
||||
graphql.NoUnmarshalJSON
|
||||
@@ -401,15 +421,15 @@ func (v *InnerQueryFragmentRandomItemTopic) GetId() testutil.ID { return v.Id }
|
||||
// GetName is a part of, and documented with, the interface InnerQueryFragmentRandomItemContent.
|
||||
func (v *InnerQueryFragmentRandomItemTopic) GetName() string { return v.Name }
|
||||
|
||||
func __unmarshalInnerQueryFragmentRandomItemContent(v *InnerQueryFragmentRandomItemContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalInnerQueryFragmentRandomItemContent(b []byte, v *InnerQueryFragmentRandomItemContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -417,13 +437,13 @@ func __unmarshalInnerQueryFragmentRandomItemContent(v *InnerQueryFragmentRandomI
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(InnerQueryFragmentRandomItemArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(InnerQueryFragmentRandomItemVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(InnerQueryFragmentRandomItemTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -444,6 +464,10 @@ type InnerQueryFragmentRandomItemTopic struct {
|
||||
|
||||
func (v *InnerQueryFragmentRandomItemTopic) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*InnerQueryFragmentRandomItemTopic
|
||||
graphql.NoUnmarshalJSON
|
||||
@@ -475,6 +499,10 @@ type InnerQueryFragmentRandomItemVideo struct {
|
||||
|
||||
func (v *InnerQueryFragmentRandomItemVideo) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*InnerQueryFragmentRandomItemVideo
|
||||
graphql.NoUnmarshalJSON
|
||||
@@ -507,6 +535,10 @@ type InnerQueryFragmentRandomLeafArticle struct {
|
||||
|
||||
func (v *InnerQueryFragmentRandomLeafArticle) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*InnerQueryFragmentRandomLeafArticle
|
||||
graphql.NoUnmarshalJSON
|
||||
@@ -552,15 +584,15 @@ func (v *InnerQueryFragmentRandomLeafVideo) implementsGraphQLInterfaceInnerQuery
|
||||
// GetTypename is a part of, and documented with, the interface InnerQueryFragmentRandomLeafLeafContent.
|
||||
func (v *InnerQueryFragmentRandomLeafVideo) GetTypename() string { return v.Typename }
|
||||
|
||||
func __unmarshalInnerQueryFragmentRandomLeafLeafContent(v *InnerQueryFragmentRandomLeafLeafContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalInnerQueryFragmentRandomLeafLeafContent(b []byte, v *InnerQueryFragmentRandomLeafLeafContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -568,10 +600,10 @@ func __unmarshalInnerQueryFragmentRandomLeafLeafContent(v *InnerQueryFragmentRan
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(InnerQueryFragmentRandomLeafArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(InnerQueryFragmentRandomLeafVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing LeafContent.__typename")
|
||||
@@ -591,6 +623,10 @@ type InnerQueryFragmentRandomLeafVideo struct {
|
||||
|
||||
func (v *InnerQueryFragmentRandomLeafVideo) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*InnerQueryFragmentRandomLeafVideo
|
||||
graphql.NoUnmarshalJSON
|
||||
@@ -637,6 +673,10 @@ type MoreVideoFieldsParentTopic struct {
|
||||
|
||||
func (v *MoreVideoFieldsParentTopic) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*MoreVideoFieldsParentTopic
|
||||
Children []json.RawMessage `json:"children"`
|
||||
@@ -656,15 +696,15 @@ func (v *MoreVideoFieldsParentTopic) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.Children
|
||||
raw := firstPass.Children
|
||||
*target = make(
|
||||
dst := &v.Children
|
||||
src := firstPass.Children
|
||||
*dst = make(
|
||||
[]MoreVideoFieldsParentTopicChildrenContent,
|
||||
len(raw))
|
||||
for i, raw := range raw {
|
||||
target := &(*target)[i]
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
err = __unmarshalMoreVideoFieldsParentTopicChildrenContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal MoreVideoFieldsParentTopic.Children: %w", err)
|
||||
@@ -712,15 +752,15 @@ func (v *MoreVideoFieldsParentTopicChildrenTopic) implementsGraphQLInterfaceMore
|
||||
// GetTypename is a part of, and documented with, the interface MoreVideoFieldsParentTopicChildrenContent.
|
||||
func (v *MoreVideoFieldsParentTopicChildrenTopic) GetTypename() *string { return v.Typename }
|
||||
|
||||
func __unmarshalMoreVideoFieldsParentTopicChildrenContent(v *MoreVideoFieldsParentTopicChildrenContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalMoreVideoFieldsParentTopicChildrenContent(b []byte, v *MoreVideoFieldsParentTopicChildrenContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -728,13 +768,13 @@ func __unmarshalMoreVideoFieldsParentTopicChildrenContent(v *MoreVideoFieldsPare
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(MoreVideoFieldsParentTopicChildrenArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(MoreVideoFieldsParentTopicChildrenVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(MoreVideoFieldsParentTopicChildrenTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -757,6 +797,10 @@ type MoreVideoFieldsParentTopicChildrenVideo struct {
|
||||
|
||||
func (v *MoreVideoFieldsParentTopicChildrenVideo) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*MoreVideoFieldsParentTopicChildrenVideo
|
||||
graphql.NoUnmarshalJSON
|
||||
@@ -786,6 +830,10 @@ type QueryFragment struct {
|
||||
|
||||
func (v *QueryFragment) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*QueryFragment
|
||||
graphql.NoUnmarshalJSON
|
||||
@@ -818,6 +866,10 @@ type VideoFields struct {
|
||||
|
||||
func (v *VideoFields) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*VideoFields
|
||||
graphql.NoUnmarshalJSON
|
||||
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
package test
|
||||
|
||||
// Code generated by github.com/Khan/genqlient, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Khan/genqlient/graphql"
|
||||
"github.com/Khan/genqlient/internal/testutil"
|
||||
)
|
||||
|
||||
// CustomMarshalResponse is returned by CustomMarshal on success.
|
||||
type CustomMarshalResponse struct {
|
||||
UsersBornOn []CustomMarshalUsersBornOnUser `json:"usersBornOn"`
|
||||
}
|
||||
|
||||
// CustomMarshalUsersBornOnUser includes the requested fields of the GraphQL type User.
|
||||
// The GraphQL type's documentation follows.
|
||||
//
|
||||
// A User is a user!
|
||||
type CustomMarshalUsersBornOnUser struct {
|
||||
// id is the user's ID.
|
||||
//
|
||||
// It is stable, unique, and opaque, like all good IDs.
|
||||
Id testutil.ID `json:"id"`
|
||||
Birthdate time.Time `json:"-"`
|
||||
}
|
||||
|
||||
func (v *CustomMarshalUsersBornOnUser) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*CustomMarshalUsersBornOnUser
|
||||
Birthdate json.RawMessage `json:"birthdate"`
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.CustomMarshalUsersBornOnUser = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
{
|
||||
dst := &v.Birthdate
|
||||
src := firstPass.Birthdate
|
||||
err = testutil.UnmarshalDate(
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal CustomMarshalUsersBornOnUser.Birthdate: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// __CustomMarshalInput is used internally by genqlient
|
||||
type __CustomMarshalInput struct {
|
||||
Date time.Time `json:"-"`
|
||||
}
|
||||
|
||||
func (v *__CustomMarshalInput) MarshalJSON() ([]byte, error) {
|
||||
|
||||
var fullObject struct {
|
||||
*__CustomMarshalInput
|
||||
Date json.RawMessage `json:"date"`
|
||||
graphql.NoMarshalJSON
|
||||
}
|
||||
fullObject.__CustomMarshalInput = v
|
||||
|
||||
{
|
||||
|
||||
dst := &fullObject.Date
|
||||
src := v.Date
|
||||
var err error
|
||||
*dst, err = testutil.MarshalDate(
|
||||
&src)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Unable to marshal __CustomMarshalInput.Date: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return json.Marshal(&fullObject)
|
||||
}
|
||||
|
||||
func CustomMarshal(
|
||||
client graphql.Client,
|
||||
date time.Time,
|
||||
) (*CustomMarshalResponse, error) {
|
||||
__input := __CustomMarshalInput{
|
||||
Date: date,
|
||||
}
|
||||
var err error
|
||||
|
||||
var retval CustomMarshalResponse
|
||||
err = client.MakeRequest(
|
||||
nil,
|
||||
"CustomMarshal",
|
||||
`
|
||||
query CustomMarshal ($date: Date!) {
|
||||
usersBornOn(date: $date) {
|
||||
id
|
||||
birthdate
|
||||
}
|
||||
}
|
||||
`,
|
||||
&retval,
|
||||
&__input,
|
||||
)
|
||||
return &retval, err
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"operations": [
|
||||
{
|
||||
"operationName": "CustomMarshal",
|
||||
"query": "\nquery CustomMarshal ($date: Date!) {\n\tusersBornOn(date: $date) {\n\t\tid\n\t\tbirthdate\n\t}\n}\n",
|
||||
"sourceLocation": "testdata/queries/CustomMarshal.graphql"
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+126
@@ -0,0 +1,126 @@
|
||||
package test
|
||||
|
||||
// Code generated by github.com/Khan/genqlient, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Khan/genqlient/graphql"
|
||||
"github.com/Khan/genqlient/internal/testutil"
|
||||
)
|
||||
|
||||
// CustomMarshalSliceResponse is returned by CustomMarshalSlice on success.
|
||||
type CustomMarshalSliceResponse struct {
|
||||
AcceptsListOfListOfListsOfDates bool `json:"acceptsListOfListOfListsOfDates"`
|
||||
WithPointer bool `json:"withPointer"`
|
||||
}
|
||||
|
||||
// __CustomMarshalSliceInput is used internally by genqlient
|
||||
type __CustomMarshalSliceInput struct {
|
||||
Datesss [][][]time.Time `json:"-"`
|
||||
Datesssp [][][]*time.Time `json:"-"`
|
||||
}
|
||||
|
||||
func (v *__CustomMarshalSliceInput) MarshalJSON() ([]byte, error) {
|
||||
|
||||
var fullObject struct {
|
||||
*__CustomMarshalSliceInput
|
||||
Datesss [][][]json.RawMessage `json:"datesss"`
|
||||
Datesssp [][][]json.RawMessage `json:"datesssp"`
|
||||
graphql.NoMarshalJSON
|
||||
}
|
||||
fullObject.__CustomMarshalSliceInput = v
|
||||
|
||||
{
|
||||
|
||||
dst := &fullObject.Datesss
|
||||
src := v.Datesss
|
||||
*dst = make(
|
||||
[][][]json.RawMessage,
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
*dst = make(
|
||||
[][]json.RawMessage,
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
*dst = make(
|
||||
[]json.RawMessage,
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
var err error
|
||||
*dst, err = testutil.MarshalDate(
|
||||
&src)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Unable to marshal __CustomMarshalSliceInput.Datesss: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
|
||||
dst := &fullObject.Datesssp
|
||||
src := v.Datesssp
|
||||
*dst = make(
|
||||
[][][]json.RawMessage,
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
*dst = make(
|
||||
[][]json.RawMessage,
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
*dst = make(
|
||||
[]json.RawMessage,
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
var err error
|
||||
*dst, err = testutil.MarshalDate(
|
||||
src)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Unable to marshal __CustomMarshalSliceInput.Datesssp: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return json.Marshal(&fullObject)
|
||||
}
|
||||
|
||||
func CustomMarshalSlice(
|
||||
client graphql.Client,
|
||||
datesss [][][]time.Time,
|
||||
datesssp [][][]*time.Time,
|
||||
) (*CustomMarshalSliceResponse, error) {
|
||||
__input := __CustomMarshalSliceInput{
|
||||
Datesss: datesss,
|
||||
Datesssp: datesssp,
|
||||
}
|
||||
var err error
|
||||
|
||||
var retval CustomMarshalSliceResponse
|
||||
err = client.MakeRequest(
|
||||
nil,
|
||||
"CustomMarshalSlice",
|
||||
`
|
||||
query CustomMarshalSlice ($datesss: [[[Date!]!]!]!, $datesssp: [[[Date!]!]!]!) {
|
||||
acceptsListOfListOfListsOfDates(datesss: $datesss)
|
||||
withPointer: acceptsListOfListOfListsOfDates(datesss: $datesssp)
|
||||
}
|
||||
`,
|
||||
&retval,
|
||||
&__input,
|
||||
)
|
||||
return &retval, err
|
||||
}
|
||||
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"operations": [
|
||||
{
|
||||
"operationName": "CustomMarshalSlice",
|
||||
"query": "\nquery CustomMarshalSlice ($datesss: [[[Date!]!]!]!, $datesssp: [[[Date!]!]!]!) {\n\tacceptsListOfListOfListsOfDates(datesss: $datesss)\n\twithPointer: acceptsListOfListOfListsOfDates(datesss: $datesssp)\n}\n",
|
||||
"sourceLocation": "testdata/queries/CustomMarshalSlice.graphql"
|
||||
}
|
||||
]
|
||||
}
|
||||
+30
@@ -3,6 +3,10 @@ package test
|
||||
// Code generated by github.com/Khan/genqlient, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Khan/genqlient/graphql"
|
||||
"github.com/Khan/genqlient/internal/testutil"
|
||||
)
|
||||
@@ -54,6 +58,32 @@ type UserQueryInput struct {
|
||||
Role Role `json:"role"`
|
||||
Names []string `json:"names"`
|
||||
HasPokemon testutil.Pokemon `json:"hasPokemon"`
|
||||
Birthdate time.Time `json:"-"`
|
||||
}
|
||||
|
||||
func (v *UserQueryInput) MarshalJSON() ([]byte, error) {
|
||||
|
||||
var fullObject struct {
|
||||
*UserQueryInput
|
||||
Birthdate json.RawMessage `json:"birthdate"`
|
||||
graphql.NoMarshalJSON
|
||||
}
|
||||
fullObject.UserQueryInput = v
|
||||
|
||||
{
|
||||
|
||||
dst := &fullObject.Birthdate
|
||||
src := v.Birthdate
|
||||
var err error
|
||||
*dst, err = testutil.MarshalDate(
|
||||
&src)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Unable to marshal UserQueryInput.Birthdate: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return json.Marshal(&fullObject)
|
||||
}
|
||||
|
||||
// __InputObjectQueryInput is used internally by genqlient
|
||||
|
||||
Vendored
+34
-26
@@ -26,6 +26,10 @@ type InterfaceListFieldRootTopic struct {
|
||||
|
||||
func (v *InterfaceListFieldRootTopic) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*InterfaceListFieldRootTopic
|
||||
Children []json.RawMessage `json:"children"`
|
||||
@@ -39,15 +43,15 @@ func (v *InterfaceListFieldRootTopic) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.Children
|
||||
raw := firstPass.Children
|
||||
*target = make(
|
||||
dst := &v.Children
|
||||
src := firstPass.Children
|
||||
*dst = make(
|
||||
[]InterfaceListFieldRootTopicChildrenContent,
|
||||
len(raw))
|
||||
for i, raw := range raw {
|
||||
target := &(*target)[i]
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
err = __unmarshalInterfaceListFieldRootTopicChildrenContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal InterfaceListFieldRootTopic.Children: %w", err)
|
||||
@@ -123,15 +127,15 @@ func (v *InterfaceListFieldRootTopicChildrenTopic) GetId() testutil.ID { return
|
||||
// GetName is a part of, and documented with, the interface InterfaceListFieldRootTopicChildrenContent.
|
||||
func (v *InterfaceListFieldRootTopicChildrenTopic) GetName() string { return v.Name }
|
||||
|
||||
func __unmarshalInterfaceListFieldRootTopicChildrenContent(v *InterfaceListFieldRootTopicChildrenContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalInterfaceListFieldRootTopicChildrenContent(b []byte, v *InterfaceListFieldRootTopicChildrenContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -139,13 +143,13 @@ func __unmarshalInterfaceListFieldRootTopicChildrenContent(v *InterfaceListField
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(InterfaceListFieldRootTopicChildrenArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(InterfaceListFieldRootTopicChildrenVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(InterfaceListFieldRootTopicChildrenTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -181,6 +185,10 @@ type InterfaceListFieldWithPointerTopic struct {
|
||||
|
||||
func (v *InterfaceListFieldWithPointerTopic) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*InterfaceListFieldWithPointerTopic
|
||||
Children []json.RawMessage `json:"children"`
|
||||
@@ -194,15 +202,15 @@ func (v *InterfaceListFieldWithPointerTopic) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.Children
|
||||
raw := firstPass.Children
|
||||
*target = make(
|
||||
dst := &v.Children
|
||||
src := firstPass.Children
|
||||
*dst = make(
|
||||
[]InterfaceListFieldWithPointerTopicChildrenContent,
|
||||
len(raw))
|
||||
for i, raw := range raw {
|
||||
target := &(*target)[i]
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
err = __unmarshalInterfaceListFieldWithPointerTopicChildrenContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal InterfaceListFieldWithPointerTopic.Children: %w", err)
|
||||
@@ -278,15 +286,15 @@ func (v *InterfaceListFieldWithPointerTopicChildrenTopic) GetId() testutil.ID {
|
||||
// GetName is a part of, and documented with, the interface InterfaceListFieldWithPointerTopicChildrenContent.
|
||||
func (v *InterfaceListFieldWithPointerTopicChildrenTopic) GetName() string { return v.Name }
|
||||
|
||||
func __unmarshalInterfaceListFieldWithPointerTopicChildrenContent(v *InterfaceListFieldWithPointerTopicChildrenContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalInterfaceListFieldWithPointerTopicChildrenContent(b []byte, v *InterfaceListFieldWithPointerTopicChildrenContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -294,13 +302,13 @@ func __unmarshalInterfaceListFieldWithPointerTopicChildrenContent(v *InterfaceLi
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(InterfaceListFieldWithPointerTopicChildrenArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(InterfaceListFieldWithPointerTopicChildrenVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(InterfaceListFieldWithPointerTopicChildrenTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
|
||||
+47
-43
@@ -86,15 +86,15 @@ func (v *InterfaceListOfListOfListsFieldListOfListsOfListsOfContentTopic) GetNam
|
||||
return v.Name
|
||||
}
|
||||
|
||||
func __unmarshalInterfaceListOfListOfListsFieldListOfListsOfListsOfContent(v *InterfaceListOfListOfListsFieldListOfListsOfListsOfContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalInterfaceListOfListOfListsFieldListOfListsOfListsOfContent(b []byte, v *InterfaceListOfListOfListsFieldListOfListsOfListsOfContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -102,13 +102,13 @@ func __unmarshalInterfaceListOfListOfListsFieldListOfListsOfListsOfContent(v *In
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(InterfaceListOfListOfListsFieldListOfListsOfListsOfContentArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(InterfaceListOfListOfListsFieldListOfListsOfListsOfContentVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(InterfaceListOfListOfListsFieldListOfListsOfListsOfContentTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -150,6 +150,10 @@ type InterfaceListOfListOfListsFieldResponse struct {
|
||||
|
||||
func (v *InterfaceListOfListOfListsFieldResponse) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*InterfaceListOfListOfListsFieldResponse
|
||||
ListOfListsOfListsOfContent [][][]json.RawMessage `json:"listOfListsOfListsOfContent"`
|
||||
@@ -164,25 +168,25 @@ func (v *InterfaceListOfListOfListsFieldResponse) UnmarshalJSON(b []byte) error
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.ListOfListsOfListsOfContent
|
||||
raw := firstPass.ListOfListsOfListsOfContent
|
||||
*target = make(
|
||||
dst := &v.ListOfListsOfListsOfContent
|
||||
src := firstPass.ListOfListsOfListsOfContent
|
||||
*dst = make(
|
||||
[][][]InterfaceListOfListOfListsFieldListOfListsOfListsOfContent,
|
||||
len(raw))
|
||||
for i, raw := range raw {
|
||||
target := &(*target)[i]
|
||||
*target = make(
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
*dst = make(
|
||||
[][]InterfaceListOfListOfListsFieldListOfListsOfListsOfContent,
|
||||
len(raw))
|
||||
for i, raw := range raw {
|
||||
target := &(*target)[i]
|
||||
*target = make(
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
*dst = make(
|
||||
[]InterfaceListOfListOfListsFieldListOfListsOfListsOfContent,
|
||||
len(raw))
|
||||
for i, raw := range raw {
|
||||
target := &(*target)[i]
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
err = __unmarshalInterfaceListOfListOfListsFieldListOfListsOfListsOfContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal InterfaceListOfListOfListsFieldResponse.ListOfListsOfListsOfContent: %w", err)
|
||||
@@ -193,26 +197,26 @@ func (v *InterfaceListOfListOfListsFieldResponse) UnmarshalJSON(b []byte) error
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.WithPointer
|
||||
raw := firstPass.WithPointer
|
||||
*target = make(
|
||||
dst := &v.WithPointer
|
||||
src := firstPass.WithPointer
|
||||
*dst = make(
|
||||
[][][]*InterfaceListOfListOfListsFieldWithPointerContent,
|
||||
len(raw))
|
||||
for i, raw := range raw {
|
||||
target := &(*target)[i]
|
||||
*target = make(
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
*dst = make(
|
||||
[][]*InterfaceListOfListOfListsFieldWithPointerContent,
|
||||
len(raw))
|
||||
for i, raw := range raw {
|
||||
target := &(*target)[i]
|
||||
*target = make(
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
*dst = make(
|
||||
[]*InterfaceListOfListOfListsFieldWithPointerContent,
|
||||
len(raw))
|
||||
for i, raw := range raw {
|
||||
target := &(*target)[i]
|
||||
*target = new(InterfaceListOfListOfListsFieldWithPointerContent)
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
*dst = new(InterfaceListOfListOfListsFieldWithPointerContent)
|
||||
err = __unmarshalInterfaceListOfListOfListsFieldWithPointerContent(
|
||||
*target, raw)
|
||||
src, *dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal InterfaceListOfListOfListsFieldResponse.WithPointer: %w", err)
|
||||
@@ -290,15 +294,15 @@ func (v *InterfaceListOfListOfListsFieldWithPointerTopic) GetId() *testutil.ID {
|
||||
// GetName is a part of, and documented with, the interface InterfaceListOfListOfListsFieldWithPointerContent.
|
||||
func (v *InterfaceListOfListOfListsFieldWithPointerTopic) GetName() *string { return v.Name }
|
||||
|
||||
func __unmarshalInterfaceListOfListOfListsFieldWithPointerContent(v *InterfaceListOfListOfListsFieldWithPointerContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalInterfaceListOfListOfListsFieldWithPointerContent(b []byte, v *InterfaceListOfListOfListsFieldWithPointerContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -306,13 +310,13 @@ func __unmarshalInterfaceListOfListOfListsFieldWithPointerContent(v *InterfaceLi
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(InterfaceListOfListOfListsFieldWithPointerArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(InterfaceListOfListOfListsFieldWithPointerVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(InterfaceListOfListOfListsFieldWithPointerTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
|
||||
Vendored
+34
-26
@@ -24,6 +24,10 @@ type InterfaceNestingRootTopic struct {
|
||||
|
||||
func (v *InterfaceNestingRootTopic) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*InterfaceNestingRootTopic
|
||||
Children []json.RawMessage `json:"children"`
|
||||
@@ -37,15 +41,15 @@ func (v *InterfaceNestingRootTopic) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.Children
|
||||
raw := firstPass.Children
|
||||
*target = make(
|
||||
dst := &v.Children
|
||||
src := firstPass.Children
|
||||
*dst = make(
|
||||
[]InterfaceNestingRootTopicChildrenContent,
|
||||
len(raw))
|
||||
for i, raw := range raw {
|
||||
target := &(*target)[i]
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
err = __unmarshalInterfaceNestingRootTopicChildrenContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal InterfaceNestingRootTopic.Children: %w", err)
|
||||
@@ -127,15 +131,15 @@ func (v *InterfaceNestingRootTopicChildrenTopic) GetParent() InterfaceNestingRoo
|
||||
return v.Parent
|
||||
}
|
||||
|
||||
func __unmarshalInterfaceNestingRootTopicChildrenContent(v *InterfaceNestingRootTopicChildrenContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalInterfaceNestingRootTopicChildrenContent(b []byte, v *InterfaceNestingRootTopicChildrenContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -143,13 +147,13 @@ func __unmarshalInterfaceNestingRootTopicChildrenContent(v *InterfaceNestingRoot
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(InterfaceNestingRootTopicChildrenArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(InterfaceNestingRootTopicChildrenVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(InterfaceNestingRootTopicChildrenTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -168,6 +172,10 @@ type InterfaceNestingRootTopicChildrenContentParentTopic struct {
|
||||
|
||||
func (v *InterfaceNestingRootTopicChildrenContentParentTopic) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*InterfaceNestingRootTopicChildrenContentParentTopic
|
||||
Children []json.RawMessage `json:"children"`
|
||||
@@ -181,15 +189,15 @@ func (v *InterfaceNestingRootTopicChildrenContentParentTopic) UnmarshalJSON(b []
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.Children
|
||||
raw := firstPass.Children
|
||||
*target = make(
|
||||
dst := &v.Children
|
||||
src := firstPass.Children
|
||||
*dst = make(
|
||||
[]InterfaceNestingRootTopicChildrenContentParentTopicChildrenContent,
|
||||
len(raw))
|
||||
for i, raw := range raw {
|
||||
target := &(*target)[i]
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
err = __unmarshalInterfaceNestingRootTopicChildrenContentParentTopicChildrenContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal InterfaceNestingRootTopicChildrenContentParentTopic.Children: %w", err)
|
||||
@@ -265,15 +273,15 @@ func (v *InterfaceNestingRootTopicChildrenContentParentTopicChildrenTopic) GetId
|
||||
return v.Id
|
||||
}
|
||||
|
||||
func __unmarshalInterfaceNestingRootTopicChildrenContentParentTopicChildrenContent(v *InterfaceNestingRootTopicChildrenContentParentTopicChildrenContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalInterfaceNestingRootTopicChildrenContentParentTopicChildrenContent(b []byte, v *InterfaceNestingRootTopicChildrenContentParentTopicChildrenContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -281,13 +289,13 @@ func __unmarshalInterfaceNestingRootTopicChildrenContentParentTopicChildrenConte
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(InterfaceNestingRootTopicChildrenContentParentTopicChildrenArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(InterfaceNestingRootTopicChildrenContentParentTopicChildrenVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(InterfaceNestingRootTopicChildrenContentParentTopicChildrenTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
|
||||
+32
-28
@@ -76,15 +76,15 @@ func (v *InterfaceNoFragmentsQueryRandomItemTopic) GetId() testutil.ID { return
|
||||
// GetName is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemContent.
|
||||
func (v *InterfaceNoFragmentsQueryRandomItemTopic) GetName() string { return v.Name }
|
||||
|
||||
func __unmarshalInterfaceNoFragmentsQueryRandomItemContent(v *InterfaceNoFragmentsQueryRandomItemContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalInterfaceNoFragmentsQueryRandomItemContent(b []byte, v *InterfaceNoFragmentsQueryRandomItemContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -92,13 +92,13 @@ func __unmarshalInterfaceNoFragmentsQueryRandomItemContent(v *InterfaceNoFragmen
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(InterfaceNoFragmentsQueryRandomItemArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(InterfaceNoFragmentsQueryRandomItemVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(InterfaceNoFragmentsQueryRandomItemTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -196,15 +196,15 @@ func (v *InterfaceNoFragmentsQueryRandomItemWithTypeNameTopic) GetId() testutil.
|
||||
// GetName is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemWithTypeNameContent.
|
||||
func (v *InterfaceNoFragmentsQueryRandomItemWithTypeNameTopic) GetName() string { return v.Name }
|
||||
|
||||
func __unmarshalInterfaceNoFragmentsQueryRandomItemWithTypeNameContent(v *InterfaceNoFragmentsQueryRandomItemWithTypeNameContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalInterfaceNoFragmentsQueryRandomItemWithTypeNameContent(b []byte, v *InterfaceNoFragmentsQueryRandomItemWithTypeNameContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -212,13 +212,13 @@ func __unmarshalInterfaceNoFragmentsQueryRandomItemWithTypeNameContent(v *Interf
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(InterfaceNoFragmentsQueryRandomItemWithTypeNameArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(InterfaceNoFragmentsQueryRandomItemWithTypeNameVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(InterfaceNoFragmentsQueryRandomItemWithTypeNameTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -254,6 +254,10 @@ type InterfaceNoFragmentsQueryResponse struct {
|
||||
|
||||
func (v *InterfaceNoFragmentsQueryResponse) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*InterfaceNoFragmentsQueryResponse
|
||||
RandomItem json.RawMessage `json:"randomItem"`
|
||||
@@ -269,10 +273,10 @@ func (v *InterfaceNoFragmentsQueryResponse) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.RandomItem
|
||||
raw := firstPass.RandomItem
|
||||
dst := &v.RandomItem
|
||||
src := firstPass.RandomItem
|
||||
err = __unmarshalInterfaceNoFragmentsQueryRandomItemContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal InterfaceNoFragmentsQueryResponse.RandomItem: %w", err)
|
||||
@@ -280,10 +284,10 @@ func (v *InterfaceNoFragmentsQueryResponse) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.RandomItemWithTypeName
|
||||
raw := firstPass.RandomItemWithTypeName
|
||||
dst := &v.RandomItemWithTypeName
|
||||
src := firstPass.RandomItemWithTypeName
|
||||
err = __unmarshalInterfaceNoFragmentsQueryRandomItemWithTypeNameContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal InterfaceNoFragmentsQueryResponse.RandomItemWithTypeName: %w", err)
|
||||
@@ -291,11 +295,11 @@ func (v *InterfaceNoFragmentsQueryResponse) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.WithPointer
|
||||
raw := firstPass.WithPointer
|
||||
*target = new(InterfaceNoFragmentsQueryWithPointerContent)
|
||||
dst := &v.WithPointer
|
||||
src := firstPass.WithPointer
|
||||
*dst = new(InterfaceNoFragmentsQueryWithPointerContent)
|
||||
err = __unmarshalInterfaceNoFragmentsQueryWithPointerContent(
|
||||
*target, raw)
|
||||
src, *dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal InterfaceNoFragmentsQueryResponse.WithPointer: %w", err)
|
||||
@@ -377,15 +381,15 @@ func (v *InterfaceNoFragmentsQueryWithPointerTopic) GetId() *testutil.ID { retur
|
||||
// GetName is a part of, and documented with, the interface InterfaceNoFragmentsQueryWithPointerContent.
|
||||
func (v *InterfaceNoFragmentsQueryWithPointerTopic) GetName() *string { return v.Name }
|
||||
|
||||
func __unmarshalInterfaceNoFragmentsQueryWithPointerContent(v *InterfaceNoFragmentsQueryWithPointerContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalInterfaceNoFragmentsQueryWithPointerContent(b []byte, v *InterfaceNoFragmentsQueryWithPointerContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -393,13 +397,13 @@ func __unmarshalInterfaceNoFragmentsQueryWithPointerContent(v *InterfaceNoFragme
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(InterfaceNoFragmentsQueryWithPointerArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(InterfaceNoFragmentsQueryWithPointerVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(InterfaceNoFragmentsQueryWithPointerTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
|
||||
+28
@@ -3,6 +3,8 @@ package test
|
||||
// Code generated by github.com/Khan/genqlient, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Khan/genqlient/graphql"
|
||||
@@ -70,6 +72,32 @@ type UserQueryInput struct {
|
||||
Role Role `json:"role"`
|
||||
Names []string `json:"names"`
|
||||
HasPokemon testutil.Pokemon `json:"hasPokemon"`
|
||||
Birthdate time.Time `json:"-"`
|
||||
}
|
||||
|
||||
func (v *UserQueryInput) MarshalJSON() ([]byte, error) {
|
||||
|
||||
var fullObject struct {
|
||||
*UserQueryInput
|
||||
Birthdate json.RawMessage `json:"birthdate"`
|
||||
graphql.NoMarshalJSON
|
||||
}
|
||||
fullObject.UserQueryInput = v
|
||||
|
||||
{
|
||||
|
||||
dst := &fullObject.Birthdate
|
||||
src := v.Birthdate
|
||||
var err error
|
||||
*dst, err = testutil.MarshalDate(
|
||||
&src)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Unable to marshal UserQueryInput.Birthdate: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return json.Marshal(&fullObject)
|
||||
}
|
||||
|
||||
// __OmitEmptyQueryInput is used internally by genqlient
|
||||
|
||||
+28
@@ -3,6 +3,8 @@ package test
|
||||
// Code generated by github.com/Khan/genqlient, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Khan/genqlient/graphql"
|
||||
@@ -77,6 +79,32 @@ type UserQueryInput struct {
|
||||
Role *Role `json:"role"`
|
||||
Names []*string `json:"names"`
|
||||
HasPokemon *testutil.Pokemon `json:"hasPokemon"`
|
||||
Birthdate *time.Time `json:"-"`
|
||||
}
|
||||
|
||||
func (v *UserQueryInput) MarshalJSON() ([]byte, error) {
|
||||
|
||||
var fullObject struct {
|
||||
*UserQueryInput
|
||||
Birthdate json.RawMessage `json:"birthdate"`
|
||||
graphql.NoMarshalJSON
|
||||
}
|
||||
fullObject.UserQueryInput = v
|
||||
|
||||
{
|
||||
|
||||
dst := &fullObject.Birthdate
|
||||
src := v.Birthdate
|
||||
var err error
|
||||
*dst, err = testutil.MarshalDate(
|
||||
src)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Unable to marshal UserQueryInput.Birthdate: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return json.Marshal(&fullObject)
|
||||
}
|
||||
|
||||
// __PointersQueryInput is used internally by genqlient
|
||||
|
||||
+28
@@ -3,6 +3,8 @@ package test
|
||||
// Code generated by github.com/Khan/genqlient, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Khan/genqlient/graphql"
|
||||
@@ -77,6 +79,32 @@ type UserQueryInput struct {
|
||||
Role Role `json:"role"`
|
||||
Names []string `json:"names"`
|
||||
HasPokemon testutil.Pokemon `json:"hasPokemon"`
|
||||
Birthdate time.Time `json:"-"`
|
||||
}
|
||||
|
||||
func (v *UserQueryInput) MarshalJSON() ([]byte, error) {
|
||||
|
||||
var fullObject struct {
|
||||
*UserQueryInput
|
||||
Birthdate json.RawMessage `json:"birthdate"`
|
||||
graphql.NoMarshalJSON
|
||||
}
|
||||
fullObject.UserQueryInput = v
|
||||
|
||||
{
|
||||
|
||||
dst := &fullObject.Birthdate
|
||||
src := v.Birthdate
|
||||
var err error
|
||||
*dst, err = testutil.MarshalDate(
|
||||
&src)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Unable to marshal UserQueryInput.Birthdate: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return json.Marshal(&fullObject)
|
||||
}
|
||||
|
||||
// __PointersQueryInput is used internally by genqlient
|
||||
|
||||
+13
-9
@@ -77,15 +77,15 @@ func (v *SimpleInlineFragmentRandomItemTopic) GetId() testutil.ID { return v.Id
|
||||
// GetName is a part of, and documented with, the interface SimpleInlineFragmentRandomItemContent.
|
||||
func (v *SimpleInlineFragmentRandomItemTopic) GetName() string { return v.Name }
|
||||
|
||||
func __unmarshalSimpleInlineFragmentRandomItemContent(v *SimpleInlineFragmentRandomItemContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalSimpleInlineFragmentRandomItemContent(b []byte, v *SimpleInlineFragmentRandomItemContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -93,13 +93,13 @@ func __unmarshalSimpleInlineFragmentRandomItemContent(v *SimpleInlineFragmentRan
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(SimpleInlineFragmentRandomItemArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(SimpleInlineFragmentRandomItemVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(SimpleInlineFragmentRandomItemTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -133,6 +133,10 @@ type SimpleInlineFragmentResponse struct {
|
||||
|
||||
func (v *SimpleInlineFragmentResponse) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*SimpleInlineFragmentResponse
|
||||
RandomItem json.RawMessage `json:"randomItem"`
|
||||
@@ -146,10 +150,10 @@ func (v *SimpleInlineFragmentResponse) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.RandomItem
|
||||
raw := firstPass.RandomItem
|
||||
dst := &v.RandomItem
|
||||
src := firstPass.RandomItem
|
||||
err = __unmarshalSimpleInlineFragmentRandomItemContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal SimpleInlineFragmentResponse.RandomItem: %w", err)
|
||||
|
||||
Vendored
+29
-17
@@ -76,15 +76,15 @@ func (v *SimpleNamedFragmentRandomItemTopic) GetId() testutil.ID { return v.Id }
|
||||
// GetName is a part of, and documented with, the interface SimpleNamedFragmentRandomItemContent.
|
||||
func (v *SimpleNamedFragmentRandomItemTopic) GetName() string { return v.Name }
|
||||
|
||||
func __unmarshalSimpleNamedFragmentRandomItemContent(v *SimpleNamedFragmentRandomItemContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalSimpleNamedFragmentRandomItemContent(b []byte, v *SimpleNamedFragmentRandomItemContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -92,13 +92,13 @@ func __unmarshalSimpleNamedFragmentRandomItemContent(v *SimpleNamedFragmentRando
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(SimpleNamedFragmentRandomItemArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(SimpleNamedFragmentRandomItemVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(SimpleNamedFragmentRandomItemTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -127,6 +127,10 @@ type SimpleNamedFragmentRandomItemVideo struct {
|
||||
|
||||
func (v *SimpleNamedFragmentRandomItemVideo) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*SimpleNamedFragmentRandomItemVideo
|
||||
graphql.NoUnmarshalJSON
|
||||
@@ -177,15 +181,15 @@ func (v *SimpleNamedFragmentRandomLeafVideo) implementsGraphQLInterfaceSimpleNam
|
||||
// GetTypename is a part of, and documented with, the interface SimpleNamedFragmentRandomLeafLeafContent.
|
||||
func (v *SimpleNamedFragmentRandomLeafVideo) GetTypename() string { return v.Typename }
|
||||
|
||||
func __unmarshalSimpleNamedFragmentRandomLeafLeafContent(v *SimpleNamedFragmentRandomLeafLeafContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalSimpleNamedFragmentRandomLeafLeafContent(b []byte, v *SimpleNamedFragmentRandomLeafLeafContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -193,10 +197,10 @@ func __unmarshalSimpleNamedFragmentRandomLeafLeafContent(v *SimpleNamedFragmentR
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(SimpleNamedFragmentRandomLeafArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(SimpleNamedFragmentRandomLeafVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing LeafContent.__typename")
|
||||
@@ -214,6 +218,10 @@ type SimpleNamedFragmentRandomLeafVideo struct {
|
||||
|
||||
func (v *SimpleNamedFragmentRandomLeafVideo) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*SimpleNamedFragmentRandomLeafVideo
|
||||
graphql.NoUnmarshalJSON
|
||||
@@ -241,6 +249,10 @@ type SimpleNamedFragmentResponse struct {
|
||||
|
||||
func (v *SimpleNamedFragmentResponse) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*SimpleNamedFragmentResponse
|
||||
RandomItem json.RawMessage `json:"randomItem"`
|
||||
@@ -255,10 +267,10 @@ func (v *SimpleNamedFragmentResponse) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.RandomItem
|
||||
raw := firstPass.RandomItem
|
||||
dst := &v.RandomItem
|
||||
src := firstPass.RandomItem
|
||||
err = __unmarshalSimpleNamedFragmentRandomItemContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal SimpleNamedFragmentResponse.RandomItem: %w", err)
|
||||
@@ -266,10 +278,10 @@ func (v *SimpleNamedFragmentResponse) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.RandomLeaf
|
||||
raw := firstPass.RandomLeaf
|
||||
dst := &v.RandomLeaf
|
||||
src := firstPass.RandomLeaf
|
||||
err = __unmarshalSimpleNamedFragmentRandomLeafLeafContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal SimpleNamedFragmentResponse.RandomLeaf: %w", err)
|
||||
|
||||
+21
-13
@@ -62,6 +62,10 @@ type StructOptionRootTopicChildrenContentParentTopic struct {
|
||||
|
||||
func (v *StructOptionRootTopicChildrenContentParentTopic) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*StructOptionRootTopicChildrenContentParentTopic
|
||||
InterfaceChildren []json.RawMessage `json:"interfaceChildren"`
|
||||
@@ -75,15 +79,15 @@ func (v *StructOptionRootTopicChildrenContentParentTopic) UnmarshalJSON(b []byte
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.InterfaceChildren
|
||||
raw := firstPass.InterfaceChildren
|
||||
*target = make(
|
||||
dst := &v.InterfaceChildren
|
||||
src := firstPass.InterfaceChildren
|
||||
*dst = make(
|
||||
[]StructOptionRootTopicChildrenContentParentTopicInterfaceChildrenContent,
|
||||
len(raw))
|
||||
for i, raw := range raw {
|
||||
target := &(*target)[i]
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
err = __unmarshalStructOptionRootTopicChildrenContentParentTopicInterfaceChildrenContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal StructOptionRootTopicChildrenContentParentTopic.InterfaceChildren: %w", err)
|
||||
@@ -169,15 +173,15 @@ func (v *StructOptionRootTopicChildrenContentParentTopicInterfaceChildrenTopic)
|
||||
return v.Id
|
||||
}
|
||||
|
||||
func __unmarshalStructOptionRootTopicChildrenContentParentTopicInterfaceChildrenContent(v *StructOptionRootTopicChildrenContentParentTopicInterfaceChildrenContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalStructOptionRootTopicChildrenContentParentTopicInterfaceChildrenContent(b []byte, v *StructOptionRootTopicChildrenContentParentTopicInterfaceChildrenContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -185,13 +189,13 @@ func __unmarshalStructOptionRootTopicChildrenContentParentTopicInterfaceChildren
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(StructOptionRootTopicChildrenContentParentTopicInterfaceChildrenArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(StructOptionRootTopicChildrenContentParentTopicInterfaceChildrenVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(StructOptionRootTopicChildrenContentParentTopicInterfaceChildrenTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -218,6 +222,10 @@ type StructOptionRootTopicChildrenContentParentTopicInterfaceChildrenVideo struc
|
||||
|
||||
func (v *StructOptionRootTopicChildrenContentParentTopicInterfaceChildrenVideo) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*StructOptionRootTopicChildrenContentParentTopicInterfaceChildrenVideo
|
||||
graphql.NoUnmarshalJSON
|
||||
|
||||
+13
-9
@@ -65,15 +65,15 @@ func (v *ItemTopic) GetId() testutil.ID { return v.Id }
|
||||
// GetName is a part of, and documented with, the interface Item.
|
||||
func (v *ItemTopic) GetName() string { return v.Name }
|
||||
|
||||
func __unmarshalItem(v *Item, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalItem(b []byte, v *Item) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -81,13 +81,13 @@ func __unmarshalItem(v *Item, m json.RawMessage) error {
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(ItemArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(ItemVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Topic":
|
||||
*v = new(ItemTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
@@ -134,6 +134,10 @@ type Resp struct {
|
||||
|
||||
func (v *Resp) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*Resp
|
||||
RandomItem json.RawMessage `json:"randomItem"`
|
||||
@@ -147,10 +151,10 @@ func (v *Resp) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.RandomItem
|
||||
raw := firstPass.RandomItem
|
||||
dst := &v.RandomItem
|
||||
src := firstPass.RandomItem
|
||||
err = __unmarshalItem(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal Resp.RandomItem: %w", err)
|
||||
|
||||
Vendored
+12
-8
@@ -40,15 +40,15 @@ func (v *UnionNoFragmentsQueryRandomLeafVideo) implementsGraphQLInterfaceUnionNo
|
||||
// GetTypename is a part of, and documented with, the interface UnionNoFragmentsQueryRandomLeafLeafContent.
|
||||
func (v *UnionNoFragmentsQueryRandomLeafVideo) GetTypename() string { return v.Typename }
|
||||
|
||||
func __unmarshalUnionNoFragmentsQueryRandomLeafLeafContent(v *UnionNoFragmentsQueryRandomLeafLeafContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshalUnionNoFragmentsQueryRandomLeafLeafContent(b []byte, v *UnionNoFragmentsQueryRandomLeafLeafContent) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := json.Unmarshal(m, &tn)
|
||||
err := json.Unmarshal(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -56,10 +56,10 @@ func __unmarshalUnionNoFragmentsQueryRandomLeafLeafContent(v *UnionNoFragmentsQu
|
||||
switch tn.TypeName {
|
||||
case "Article":
|
||||
*v = new(UnionNoFragmentsQueryRandomLeafArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "Video":
|
||||
*v = new(UnionNoFragmentsQueryRandomLeafVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
return json.Unmarshal(b, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing LeafContent.__typename")
|
||||
@@ -81,6 +81,10 @@ type UnionNoFragmentsQueryResponse struct {
|
||||
|
||||
func (v *UnionNoFragmentsQueryResponse) UnmarshalJSON(b []byte) error {
|
||||
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var firstPass struct {
|
||||
*UnionNoFragmentsQueryResponse
|
||||
RandomLeaf json.RawMessage `json:"randomLeaf"`
|
||||
@@ -94,10 +98,10 @@ func (v *UnionNoFragmentsQueryResponse) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.RandomLeaf
|
||||
raw := firstPass.RandomLeaf
|
||||
dst := &v.RandomLeaf
|
||||
src := firstPass.RandomLeaf
|
||||
err = __unmarshalUnionNoFragmentsQueryRandomLeafLeafContent(
|
||||
target, raw)
|
||||
src, dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal UnionNoFragmentsQueryResponse.RandomLeaf: %w", err)
|
||||
|
||||
+30
@@ -3,6 +3,10 @@ package test
|
||||
// Code generated by github.com/Khan/genqlient, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Khan/genqlient/graphql"
|
||||
"github.com/Khan/genqlient/internal/testutil"
|
||||
)
|
||||
@@ -34,6 +38,32 @@ type UserQueryInput struct {
|
||||
Role Role `json:"role"`
|
||||
Names []string `json:"names"`
|
||||
HasPokemon testutil.Pokemon `json:"hasPokemon"`
|
||||
Birthdate time.Time `json:"-"`
|
||||
}
|
||||
|
||||
func (v *UserQueryInput) MarshalJSON() ([]byte, error) {
|
||||
|
||||
var fullObject struct {
|
||||
*UserQueryInput
|
||||
Birthdate json.RawMessage `json:"birthdate"`
|
||||
graphql.NoMarshalJSON
|
||||
}
|
||||
fullObject.UserQueryInput = v
|
||||
|
||||
{
|
||||
|
||||
dst := &fullObject.Birthdate
|
||||
src := v.Birthdate
|
||||
var err error
|
||||
*dst, err = testutil.MarshalDate(
|
||||
&src)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Unable to marshal UserQueryInput.Birthdate: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return json.Marshal(&fullObject)
|
||||
}
|
||||
|
||||
// __unexportedInput is used internally by genqlient
|
||||
|
||||
+99
-18
@@ -61,8 +61,9 @@ type (
|
||||
// goOpaqueType represents a user-defined or builtin type, often used to
|
||||
// represent a GraphQL scalar. (See Config.Bindings for more context.)
|
||||
goOpaqueType struct {
|
||||
GoRef string
|
||||
GraphQLName string
|
||||
GoRef string
|
||||
GraphQLName string
|
||||
Marshaler, Unmarshaler string
|
||||
}
|
||||
// goSliceType represents the Go type []Elem, used to represent GraphQL
|
||||
// list types.
|
||||
@@ -132,6 +133,7 @@ type goStructType struct {
|
||||
IsInput bool
|
||||
Selection ast.SelectionSet
|
||||
descriptionInfo
|
||||
Generator *generator // for the convenience of the template
|
||||
}
|
||||
|
||||
type goStructField struct {
|
||||
@@ -156,10 +158,74 @@ func (field *goStructField) IsEmbedded() bool {
|
||||
return field.GoName == ""
|
||||
}
|
||||
|
||||
// unmarshaler returns:
|
||||
// - the name of the function to use to unmarshal this field
|
||||
// - true if this is a fully-qualified name (false if it is a package-local
|
||||
// unqualified name)
|
||||
// - true if we need to generate an unmarshaler at all, false if the default
|
||||
// behavior will suffice
|
||||
func (field *goStructField) unmarshaler() (qualifiedName string, needsImport bool, needsUnmarshaler bool) {
|
||||
switch typ := field.GoType.Unwrap().(type) {
|
||||
case *goOpaqueType:
|
||||
if typ.Unmarshaler != "" {
|
||||
return typ.Unmarshaler, true, true
|
||||
}
|
||||
case *goInterfaceType:
|
||||
return "__unmarshal" + typ.Reference(), false, true
|
||||
}
|
||||
return "encoding/json.Unmarshal", true, field.IsEmbedded()
|
||||
}
|
||||
|
||||
// NeedsUnmarshaler returns true if this field needs special handling when
|
||||
// unmarshaling, e.g. if it's of interface type, embedded, or has a
|
||||
// user-specified custom unmarshaler.
|
||||
func (field *goStructField) NeedsUnmarshaler() bool {
|
||||
_, _, ok := field.unmarshaler()
|
||||
return ok
|
||||
}
|
||||
|
||||
// Unmarshaler returns the Go name of the function to use to unmarshal this
|
||||
// field (which may be "json.Unmarshal" if there's not a special one).
|
||||
func (field *goStructField) Unmarshaler(g *generator) (string, error) {
|
||||
name, needsImport, _ := field.unmarshaler()
|
||||
if needsImport {
|
||||
return g.ref(name)
|
||||
}
|
||||
return name, nil
|
||||
}
|
||||
|
||||
// marshaler returns:
|
||||
// - the fully-qualified name of the function to use to marshal this field
|
||||
// - true if we need to generate an marshaler at all, false if the default
|
||||
// behavior will suffice
|
||||
func (field *goStructField) marshaler() (qualifiedName string, needsMarshaler bool) {
|
||||
// (there are no interfaces on the input side)
|
||||
opaque, ok := field.GoType.Unwrap().(*goOpaqueType)
|
||||
if ok && opaque.Marshaler != "" {
|
||||
return opaque.Marshaler, true
|
||||
}
|
||||
return "encoding/json.Marshal", field.IsEmbedded()
|
||||
}
|
||||
|
||||
// NeedsMarshaler returns true if this field needs special handling when
|
||||
// marshaling, e.g. if it has a user-specified custom marshaler.
|
||||
func (field *goStructField) NeedsMarshaler() bool {
|
||||
_, ok := field.marshaler()
|
||||
return ok
|
||||
}
|
||||
|
||||
// Marshaler returns the Go name of the function to use to marshal this
|
||||
// field (which may be "json.Marshal" if there's not a special one).
|
||||
func (field *goStructField) Marshaler(g *generator) (string, error) {
|
||||
name, _ := field.marshaler()
|
||||
// Unlike unmarshaler, we never have a local name, and always need g.ref.
|
||||
return g.ref(name)
|
||||
}
|
||||
|
||||
func (typ *goStructType) WriteDefinition(w io.Writer, g *generator) error {
|
||||
writeDescription(w, structDescription(typ))
|
||||
|
||||
needUnmarshaler := false
|
||||
needUnmarshaler, needMarshaler := false, false
|
||||
fmt.Fprintf(w, "type %s struct {\n", typ.GoName)
|
||||
for _, field := range typ.Fields {
|
||||
writeDescription(w, field.Description)
|
||||
@@ -168,24 +234,24 @@ func (typ *goStructType) WriteDefinition(w io.Writer, g *generator) error {
|
||||
jsonTag += ",omitempty"
|
||||
}
|
||||
jsonTag += `"`
|
||||
if field.IsAbstract() {
|
||||
// abstract types are handled in our UnmarshalJSON (see below)
|
||||
if !typ.IsInput && field.NeedsUnmarshaler() {
|
||||
// certain types are handled in our UnmarshalJSON (see below)
|
||||
needUnmarshaler = true
|
||||
jsonTag = `"-"`
|
||||
}
|
||||
if field.IsEmbedded() {
|
||||
// embedded fields also need UnmarshalJSON handling (see below)
|
||||
needUnmarshaler = true
|
||||
fmt.Fprintf(w, "\t%s `json:\"-\"`\n", field.GoType.Unwrap().Reference())
|
||||
} else {
|
||||
fmt.Fprintf(w, "\t%s %s `json:%s`\n",
|
||||
field.GoName, field.GoType.Reference(), jsonTag)
|
||||
if typ.IsInput && field.NeedsMarshaler() {
|
||||
needMarshaler = true
|
||||
jsonTag = `"-"`
|
||||
}
|
||||
// Note for embedded types field.GoName is "", which produces the code
|
||||
// we want!
|
||||
fmt.Fprintf(w, "\t%s %s `json:%s`\n",
|
||||
field.GoName, field.GoType.Reference(), jsonTag)
|
||||
}
|
||||
fmt.Fprintf(w, "}\n")
|
||||
|
||||
// Now, if needed, write the unmarshaler. We need one if we have any
|
||||
// interface-typed fields, or any embedded fields.
|
||||
// Now, if needed, write the marshaler/unmarshaler. We need one if we have
|
||||
// any interface-typed fields, or any embedded fields.
|
||||
//
|
||||
// For interface-typed fields, ideally we'd write an UnmarshalJSON method
|
||||
// on the field, but you can't add a method to an interface. So we write a
|
||||
@@ -204,13 +270,28 @@ func (typ *goStructType) WriteDefinition(w io.Writer, g *generator) error {
|
||||
// JSON library will only fill one of those (the least-nested one); we want
|
||||
// to fill them all.
|
||||
//
|
||||
// For fields with a custom marshaler or unmarshaler, we do basically the
|
||||
// same thing as interface-typed fields, except the user has defined the
|
||||
// helper.
|
||||
//
|
||||
// Note that in all cases we need only write an unmarshaler if this is an
|
||||
// input type, and a marshaler if it's an output type.
|
||||
//
|
||||
// TODO(benkraft): If/when proposal #5901 is implemented (Go 1.18 at the
|
||||
// earliest), we may be able to do some of this a simpler way.
|
||||
if !needUnmarshaler {
|
||||
return nil
|
||||
if needUnmarshaler {
|
||||
err := g.render("unmarshal.go.tmpl", w, typ)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return g.render("unmarshal.go.tmpl", w, typ)
|
||||
if needMarshaler {
|
||||
err := g.render("marshal.go.tmpl", w, typ)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (typ *goStructType) Reference() string { return typ.GoName }
|
||||
|
||||
+49
-52
@@ -2,23 +2,25 @@
|
||||
UnmarshalJSON from the function it follows) */}}
|
||||
|
||||
func (v *{{.GoName}}) UnmarshalJSON(b []byte) error {
|
||||
{{/* We want to specially handle the abstract or embedded fields, but
|
||||
unmarshal everything else normally. To handle abstract fields,
|
||||
first we unmarshal them into a json.RawMessage, and then handle those
|
||||
further, below. Embedded fields we just unmarshal directly into the
|
||||
embedded value. For the rest, we just want to call json.Unmarshal.
|
||||
But if we do that naively on a value of type `.Type`, it will call
|
||||
this function again, and recurse infinitely. So we make a wrapper
|
||||
type which embeds both this type and NoUmnarshalJSON, which prevents
|
||||
either's UnmarshalJSON method from being promoted. For more on why
|
||||
this is so difficult, see
|
||||
{{/* Standard convention for unmarshalers is to no-op on null. */}}
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
{{/* We want to specially handle certain fields, but unmarshal everything
|
||||
else normally. To handle abstract fields and fields with custom
|
||||
unmarshalers, first we unmarshal them into a json.RawMessage, and then
|
||||
handle those further, below. Embedded fields don't need the
|
||||
json.RawMessage; we just use our input again. Either way, we first
|
||||
want to call json.Unmarshal on the receiver (v). But if we do that
|
||||
naively on a value of type `.Type`, it will call this function again,
|
||||
and recurse infinitely. So we make a wrapper type which embeds both
|
||||
this type and NoUmnarshalJSON, which prevents either's UnmarshalJSON
|
||||
method from being promoted. For more on why this is so difficult, see
|
||||
https://github.com/benjaminjkraft/notes/blob/master/go-json-interfaces.md.
|
||||
(Note there are a few different ways "hide" the method, but this one
|
||||
seems to be the best option that works if this type has embedded types
|
||||
with UnmarshalJSON methods.)
|
||||
TODO(benkraft)): Ensure `{{.Type}}Wrapper` won't collide with any
|
||||
other type we need. (For the most part it being locally-scoped saves
|
||||
us; it's not clear if this can be a problem in practice.)
|
||||
*/}}
|
||||
|
||||
{{/* TODO(benkraft): Omit/simplify the first pass if all fields are
|
||||
@@ -26,7 +28,7 @@ func (v *{{.GoName}}) UnmarshalJSON(b []byte) error {
|
||||
var firstPass struct{
|
||||
*{{.GoName}}
|
||||
{{range .Fields -}}
|
||||
{{if and .IsAbstract (not .IsEmbedded) -}}
|
||||
{{if and .NeedsUnmarshaler (not .IsEmbedded) -}}
|
||||
{{.GoName}} {{repeat .GoType.SliceDepth "[]"}}{{ref "encoding/json.RawMessage"}} `json:"{{.JSONName}}"`
|
||||
{{end -}}
|
||||
{{end -}}
|
||||
@@ -43,77 +45,71 @@ func (v *{{.GoName}}) UnmarshalJSON(b []byte) error {
|
||||
|
||||
{{/* Now, handle the fields needing special handling. */}}
|
||||
{{range $field := .Fields -}}
|
||||
{{if $field.NeedsUnmarshaler -}}
|
||||
{{if $field.IsEmbedded -}}
|
||||
{{/* Embedded fields are easier: we just unmarshal the same input into
|
||||
them. (They're also easier because they can't be lists, since they
|
||||
arise from GraphQL fragment spreads.) */ -}}
|
||||
{{if $field.IsAbstract -}}
|
||||
{{/* Except if they're both abstract and embedded, in which case we need to
|
||||
call the unmarshal-helper instead. Luckily, we don't embed
|
||||
slice-typed fields, so we don't need the full generality we handle
|
||||
below. */ -}}
|
||||
err = __unmarshal{{$field.GoType.Unwrap.Reference}}(
|
||||
err = {{$field.Unmarshaler $.Generator}}(
|
||||
b, &v.{{$field.GoType.Unwrap.Reference}})
|
||||
{{else -}}
|
||||
err = json.Unmarshal(
|
||||
b, &v.{{$field.GoType.Unwrap.Reference}})
|
||||
{{end -}}{{/* inner if .IsAbstract */ -}}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
{{else if $field.IsAbstract -}}
|
||||
{{/* First, for abstract fields, call the unmarshal-helper.
|
||||
This gets a little complicated because we may have a slice field.
|
||||
So what we do is basically, for each field of type `[][]...[]MyType`:
|
||||
{{else -}}
|
||||
{{/* For other fields (abstract or custom unmarshaler), first, call the
|
||||
unmarshaler (our unmarshal-helper, or the user-specified one,
|
||||
respectively). This gets a little complicated because we may have
|
||||
a slice field. So what we do is basically, for each field of type
|
||||
`[][]...[]MyType`:
|
||||
|
||||
target := &v.MyField // *[][]...[]MyType
|
||||
raw := firstPass.MyField // [][]...[]json.RawMessage
|
||||
dst := &v.MyField // *[][]...[]MyType
|
||||
src := firstPass.MyField // [][]...[]json.RawMessage
|
||||
|
||||
// repeat the following three lines n times; each time, inside
|
||||
// the loop we have one less layer of slice on raw and target
|
||||
*target = make([][]...[]MyType, len(raw))
|
||||
for i, raw := range raw {
|
||||
// We need the &(*target)[i] because at each stage we want to
|
||||
// keep target as a pointer. (It only really has to be a
|
||||
// the loop we have one less layer of slice on src and dst
|
||||
*dst = make([][]...[]MyType, len(src))
|
||||
for i, src := range src {
|
||||
// We need the &(*dst)[i] because at each stage we want to
|
||||
// keep dst as a pointer. (It only really has to be a
|
||||
// pointer at the innermost level, but it's easiest to be
|
||||
// consistent.)
|
||||
target := &(*target)[i]
|
||||
|
||||
// (now we have `target *MyType` and `raw json.RawMessage`)
|
||||
__unmarshalMyType(target, raw)
|
||||
dst := &(*dst)[i]
|
||||
|
||||
// (now we have `dst *MyType` and `src json.RawMessage`)
|
||||
__unmarshalMyType(dst, src)
|
||||
|
||||
} // (also n times)
|
||||
|
||||
Note that if the field also uses a pointer (`[][]...[]*MyType`), we
|
||||
now pass around `*[][]...[]*MyType`; again in principle
|
||||
`[][]...[]*MyType` would work but require more special-casing. Thus
|
||||
in the innermost loop, `target` is of type `**MyType`, so we have to
|
||||
pass `*target` to the unmarshal-helper. Of course, since MyType is an
|
||||
in the innermost loop, `dst` is of type `**MyType`, so we have to
|
||||
pass `*dst` to the unmarshaler. Of course, since MyType is an
|
||||
interface, I'm not sure why you'd any of that anyway.
|
||||
|
||||
One additional trick is we wrap everything above in a block ({ ... }),
|
||||
so that the variables target and raw may take on different types for
|
||||
so that the variables dst and src may take on different types for
|
||||
each field we are handling, which would otherwise conflict. (We could
|
||||
instead suffix the names, but that makes things much harder to read.)
|
||||
*/}}
|
||||
{
|
||||
target := &v.{{$field.GoName}}
|
||||
raw := firstPass.{{$field.GoName}}
|
||||
dst := &v.{{$field.GoName}}
|
||||
src := firstPass.{{$field.GoName}}
|
||||
{{range $i := intRange $field.GoType.SliceDepth -}}
|
||||
*target = make(
|
||||
*dst = make(
|
||||
{{repeat (sub $field.GoType.SliceDepth $i) "[]"}}{{if $field.GoType.IsPointer}}*{{end}}{{$field.GoType.Unwrap.Reference}},
|
||||
len(raw))
|
||||
for i, raw := range raw {
|
||||
target := &(*target)[i]
|
||||
len(src))
|
||||
for i, src := range src {
|
||||
dst := &(*dst)[i]
|
||||
{{end -}}
|
||||
{{if $field.GoType.IsPointer -}}
|
||||
{{/* In this case, the parent for loop did `make([]*MyType, ...)` and
|
||||
we have a pointer into that list. But we actually still need to
|
||||
initialize the *elements* of the list. */ -}}
|
||||
*target = new({{$field.GoType.Unwrap.Reference}})
|
||||
*dst = new({{$field.GoType.Unwrap.Reference}})
|
||||
{{end -}}
|
||||
err = __unmarshal{{$field.GoType.Unwrap.Reference}}(
|
||||
{{if $field.GoType.IsPointer}}*{{end}}target, raw)
|
||||
err = {{$field.Unmarshaler $.Generator}}(
|
||||
src, {{if $field.GoType.IsPointer}}*{{end}}dst)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal {{$.GoName}}.{{$field.GoName}}: %w", err)
|
||||
@@ -122,7 +118,8 @@ func (v *{{.GoName}}) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
{{end -}}
|
||||
}
|
||||
{{end -}}{{/* end if .IsEmbedded + else if .IsAbstract */ -}}
|
||||
{{end -}}{{/* end if/else .IsEmbedded */ -}}
|
||||
{{end -}}{{/* end if .NeedsUnmarshaler */ -}}
|
||||
{{end}}{{/* end range .Fields */ -}}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
{{/* (the blank lines at the start are intentional, to separate
|
||||
the helper from the function it follows) */}}
|
||||
|
||||
func __unmarshal{{.GoName}}(v *{{.GoName}}, m {{ref "encoding/json.RawMessage"}}) error {
|
||||
if string(m) == "null" {
|
||||
func __unmarshal{{.GoName}}(b []byte, v *{{.GoName}}) error {
|
||||
if string(b) == "null" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var tn struct {
|
||||
TypeName string `json:"__typename"`
|
||||
}
|
||||
err := {{ref "encoding/json.Unmarshal"}}(m, &tn)
|
||||
err := {{ref "encoding/json.Unmarshal"}}(b, &tn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -18,7 +18,7 @@ func __unmarshal{{.GoName}}(v *{{.GoName}}, m {{ref "encoding/json.RawMessage"}}
|
||||
{{range .Implementations -}}
|
||||
case "{{.GraphQLName}}":
|
||||
*v = new({{.GoName}})
|
||||
return {{ref "encoding/json.Unmarshal"}}(m, *v)
|
||||
return {{ref "encoding/json.Unmarshal"}}(b, *v)
|
||||
{{end -}}
|
||||
case "":
|
||||
{{/* Likely if we're making a request to a mock server and the author
|
||||
|
||||
Reference in New Issue
Block a user