diff --git a/generate/testdata/snapshots/TestGenerate-InterfaceListField.graphql-InterfaceListField.graphql.go b/generate/testdata/snapshots/TestGenerate-InterfaceListField.graphql-InterfaceListField.graphql.go index 828fd6ef..df0cea50 100644 --- a/generate/testdata/snapshots/TestGenerate-InterfaceListField.graphql-InterfaceListField.graphql.go +++ b/generate/testdata/snapshots/TestGenerate-InterfaceListField.graphql-InterfaceListField.graphql.go @@ -65,21 +65,65 @@ type InterfaceListFieldRootTopicChildrenArticle struct { Name string `json:"name"` } -// InterfaceListFieldRootTopicChildrenContent includes the requested fields of the GraphQL type Content. +// InterfaceListFieldRootTopicChildrenContent includes the requested fields of the GraphQL interface Content. +// +// InterfaceListFieldRootTopicChildrenContent is implemented by the following types: +// InterfaceListFieldRootTopicChildrenArticle +// InterfaceListFieldRootTopicChildrenVideo +// InterfaceListFieldRootTopicChildrenTopic +// // The GraphQL type's documentation follows. // // Content is implemented by various types like Article, Video, and Topic. type InterfaceListFieldRootTopicChildrenContent interface { implementsGraphQLInterfaceInterfaceListFieldRootTopicChildrenContent() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string + // GetId returns the interface-field "id" from its implementation. + // The GraphQL interface field's documentation follows. + // + // ID is the identifier of the content. + GetId() testutil.ID + // GetName returns the interface-field "name" from its implementation. + GetName() string } func (v *InterfaceListFieldRootTopicChildrenArticle) implementsGraphQLInterfaceInterfaceListFieldRootTopicChildrenContent() { } + +// GetTypename is a part of, and documented with, the interface InterfaceListFieldRootTopicChildrenContent. +func (v *InterfaceListFieldRootTopicChildrenArticle) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface InterfaceListFieldRootTopicChildrenContent. +func (v *InterfaceListFieldRootTopicChildrenArticle) GetId() testutil.ID { return v.Id } + +// GetName is a part of, and documented with, the interface InterfaceListFieldRootTopicChildrenContent. +func (v *InterfaceListFieldRootTopicChildrenArticle) GetName() string { return v.Name } + func (v *InterfaceListFieldRootTopicChildrenVideo) implementsGraphQLInterfaceInterfaceListFieldRootTopicChildrenContent() { } + +// GetTypename is a part of, and documented with, the interface InterfaceListFieldRootTopicChildrenContent. +func (v *InterfaceListFieldRootTopicChildrenVideo) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface InterfaceListFieldRootTopicChildrenContent. +func (v *InterfaceListFieldRootTopicChildrenVideo) GetId() testutil.ID { return v.Id } + +// GetName is a part of, and documented with, the interface InterfaceListFieldRootTopicChildrenContent. +func (v *InterfaceListFieldRootTopicChildrenVideo) GetName() string { return v.Name } + func (v *InterfaceListFieldRootTopicChildrenTopic) implementsGraphQLInterfaceInterfaceListFieldRootTopicChildrenContent() { } +// GetTypename is a part of, and documented with, the interface InterfaceListFieldRootTopicChildrenContent. +func (v *InterfaceListFieldRootTopicChildrenTopic) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface InterfaceListFieldRootTopicChildrenContent. +func (v *InterfaceListFieldRootTopicChildrenTopic) GetId() testutil.ID { return v.Id } + +// 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" { return nil @@ -174,21 +218,65 @@ type InterfaceListFieldWithPointerTopicChildrenArticle struct { Name string `json:"name"` } -// InterfaceListFieldWithPointerTopicChildrenContent includes the requested fields of the GraphQL type Content. +// InterfaceListFieldWithPointerTopicChildrenContent includes the requested fields of the GraphQL interface Content. +// +// InterfaceListFieldWithPointerTopicChildrenContent is implemented by the following types: +// InterfaceListFieldWithPointerTopicChildrenArticle +// InterfaceListFieldWithPointerTopicChildrenVideo +// InterfaceListFieldWithPointerTopicChildrenTopic +// // The GraphQL type's documentation follows. // // Content is implemented by various types like Article, Video, and Topic. type InterfaceListFieldWithPointerTopicChildrenContent interface { implementsGraphQLInterfaceInterfaceListFieldWithPointerTopicChildrenContent() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string + // GetId returns the interface-field "id" from its implementation. + // The GraphQL interface field's documentation follows. + // + // ID is the identifier of the content. + GetId() testutil.ID + // GetName returns the interface-field "name" from its implementation. + GetName() string } func (v *InterfaceListFieldWithPointerTopicChildrenArticle) implementsGraphQLInterfaceInterfaceListFieldWithPointerTopicChildrenContent() { } + +// GetTypename is a part of, and documented with, the interface InterfaceListFieldWithPointerTopicChildrenContent. +func (v *InterfaceListFieldWithPointerTopicChildrenArticle) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface InterfaceListFieldWithPointerTopicChildrenContent. +func (v *InterfaceListFieldWithPointerTopicChildrenArticle) GetId() testutil.ID { return v.Id } + +// GetName is a part of, and documented with, the interface InterfaceListFieldWithPointerTopicChildrenContent. +func (v *InterfaceListFieldWithPointerTopicChildrenArticle) GetName() string { return v.Name } + func (v *InterfaceListFieldWithPointerTopicChildrenVideo) implementsGraphQLInterfaceInterfaceListFieldWithPointerTopicChildrenContent() { } + +// GetTypename is a part of, and documented with, the interface InterfaceListFieldWithPointerTopicChildrenContent. +func (v *InterfaceListFieldWithPointerTopicChildrenVideo) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface InterfaceListFieldWithPointerTopicChildrenContent. +func (v *InterfaceListFieldWithPointerTopicChildrenVideo) GetId() testutil.ID { return v.Id } + +// GetName is a part of, and documented with, the interface InterfaceListFieldWithPointerTopicChildrenContent. +func (v *InterfaceListFieldWithPointerTopicChildrenVideo) GetName() string { return v.Name } + func (v *InterfaceListFieldWithPointerTopicChildrenTopic) implementsGraphQLInterfaceInterfaceListFieldWithPointerTopicChildrenContent() { } +// GetTypename is a part of, and documented with, the interface InterfaceListFieldWithPointerTopicChildrenContent. +func (v *InterfaceListFieldWithPointerTopicChildrenTopic) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface InterfaceListFieldWithPointerTopicChildrenContent. +func (v *InterfaceListFieldWithPointerTopicChildrenTopic) GetId() testutil.ID { return v.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" { return nil diff --git a/generate/testdata/snapshots/TestGenerate-InterfaceListOfListsOfListsField.graphql-InterfaceListOfListsOfListsField.graphql.go b/generate/testdata/snapshots/TestGenerate-InterfaceListOfListsOfListsField.graphql-InterfaceListOfListsOfListsField.graphql.go index 986177de..80bc4632 100644 --- a/generate/testdata/snapshots/TestGenerate-InterfaceListOfListsOfListsField.graphql-InterfaceListOfListsOfListsField.graphql.go +++ b/generate/testdata/snapshots/TestGenerate-InterfaceListOfListsOfListsField.graphql-InterfaceListOfListsOfListsField.graphql.go @@ -10,21 +10,83 @@ import ( "github.com/Khan/genqlient/internal/testutil" ) -// InterfaceListOfListOfListsFieldListOfListsOfListsOfContent includes the requested fields of the GraphQL type Content. +// InterfaceListOfListOfListsFieldListOfListsOfListsOfContent includes the requested fields of the GraphQL interface Content. +// +// InterfaceListOfListOfListsFieldListOfListsOfListsOfContent is implemented by the following types: +// InterfaceListOfListOfListsFieldListOfListsOfListsOfContentArticle +// InterfaceListOfListOfListsFieldListOfListsOfListsOfContentVideo +// InterfaceListOfListOfListsFieldListOfListsOfListsOfContentTopic +// // The GraphQL type's documentation follows. // // Content is implemented by various types like Article, Video, and Topic. type InterfaceListOfListOfListsFieldListOfListsOfListsOfContent interface { implementsGraphQLInterfaceInterfaceListOfListOfListsFieldListOfListsOfListsOfContent() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string + // GetId returns the interface-field "id" from its implementation. + // The GraphQL interface field's documentation follows. + // + // ID is the identifier of the content. + GetId() testutil.ID + // GetName returns the interface-field "name" from its implementation. + GetName() string } func (v *InterfaceListOfListOfListsFieldListOfListsOfListsOfContentArticle) implementsGraphQLInterfaceInterfaceListOfListOfListsFieldListOfListsOfListsOfContent() { } + +// GetTypename is a part of, and documented with, the interface InterfaceListOfListOfListsFieldListOfListsOfListsOfContent. +func (v *InterfaceListOfListOfListsFieldListOfListsOfListsOfContentArticle) GetTypename() string { + return v.Typename +} + +// GetId is a part of, and documented with, the interface InterfaceListOfListOfListsFieldListOfListsOfListsOfContent. +func (v *InterfaceListOfListOfListsFieldListOfListsOfListsOfContentArticle) GetId() testutil.ID { + return v.Id +} + +// GetName is a part of, and documented with, the interface InterfaceListOfListOfListsFieldListOfListsOfListsOfContent. +func (v *InterfaceListOfListOfListsFieldListOfListsOfListsOfContentArticle) GetName() string { + return v.Name +} + func (v *InterfaceListOfListOfListsFieldListOfListsOfListsOfContentVideo) implementsGraphQLInterfaceInterfaceListOfListOfListsFieldListOfListsOfListsOfContent() { } + +// GetTypename is a part of, and documented with, the interface InterfaceListOfListOfListsFieldListOfListsOfListsOfContent. +func (v *InterfaceListOfListOfListsFieldListOfListsOfListsOfContentVideo) GetTypename() string { + return v.Typename +} + +// GetId is a part of, and documented with, the interface InterfaceListOfListOfListsFieldListOfListsOfListsOfContent. +func (v *InterfaceListOfListOfListsFieldListOfListsOfListsOfContentVideo) GetId() testutil.ID { + return v.Id +} + +// GetName is a part of, and documented with, the interface InterfaceListOfListOfListsFieldListOfListsOfListsOfContent. +func (v *InterfaceListOfListOfListsFieldListOfListsOfListsOfContentVideo) GetName() string { + return v.Name +} + func (v *InterfaceListOfListOfListsFieldListOfListsOfListsOfContentTopic) implementsGraphQLInterfaceInterfaceListOfListOfListsFieldListOfListsOfListsOfContent() { } +// GetTypename is a part of, and documented with, the interface InterfaceListOfListOfListsFieldListOfListsOfListsOfContent. +func (v *InterfaceListOfListOfListsFieldListOfListsOfListsOfContentTopic) GetTypename() string { + return v.Typename +} + +// GetId is a part of, and documented with, the interface InterfaceListOfListOfListsFieldListOfListsOfListsOfContent. +func (v *InterfaceListOfListOfListsFieldListOfListsOfListsOfContentTopic) GetId() testutil.ID { + return v.Id +} + +// GetName is a part of, and documented with, the interface InterfaceListOfListOfListsFieldListOfListsOfListsOfContent. +func (v *InterfaceListOfListOfListsFieldListOfListsOfListsOfContentTopic) GetName() string { + return v.Name +} + func __unmarshalInterfaceListOfListOfListsFieldListOfListsOfListsOfContent(v *InterfaceListOfListOfListsFieldListOfListsOfListsOfContent, m json.RawMessage) error { if string(m) == "null" { return nil @@ -165,21 +227,65 @@ type InterfaceListOfListOfListsFieldWithPointerArticle struct { Name *string `json:"name"` } -// InterfaceListOfListOfListsFieldWithPointerContent includes the requested fields of the GraphQL type Content. +// InterfaceListOfListOfListsFieldWithPointerContent includes the requested fields of the GraphQL interface Content. +// +// InterfaceListOfListOfListsFieldWithPointerContent is implemented by the following types: +// InterfaceListOfListOfListsFieldWithPointerArticle +// InterfaceListOfListOfListsFieldWithPointerVideo +// InterfaceListOfListOfListsFieldWithPointerTopic +// // The GraphQL type's documentation follows. // // Content is implemented by various types like Article, Video, and Topic. type InterfaceListOfListOfListsFieldWithPointerContent interface { implementsGraphQLInterfaceInterfaceListOfListOfListsFieldWithPointerContent() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string + // GetId returns the interface-field "id" from its implementation. + // The GraphQL interface field's documentation follows. + // + // ID is the identifier of the content. + GetId() *testutil.ID + // GetName returns the interface-field "name" from its implementation. + GetName() *string } func (v *InterfaceListOfListOfListsFieldWithPointerArticle) implementsGraphQLInterfaceInterfaceListOfListOfListsFieldWithPointerContent() { } + +// GetTypename is a part of, and documented with, the interface InterfaceListOfListOfListsFieldWithPointerContent. +func (v *InterfaceListOfListOfListsFieldWithPointerArticle) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface InterfaceListOfListOfListsFieldWithPointerContent. +func (v *InterfaceListOfListOfListsFieldWithPointerArticle) GetId() *testutil.ID { return v.Id } + +// GetName is a part of, and documented with, the interface InterfaceListOfListOfListsFieldWithPointerContent. +func (v *InterfaceListOfListOfListsFieldWithPointerArticle) GetName() *string { return v.Name } + func (v *InterfaceListOfListOfListsFieldWithPointerVideo) implementsGraphQLInterfaceInterfaceListOfListOfListsFieldWithPointerContent() { } + +// GetTypename is a part of, and documented with, the interface InterfaceListOfListOfListsFieldWithPointerContent. +func (v *InterfaceListOfListOfListsFieldWithPointerVideo) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface InterfaceListOfListOfListsFieldWithPointerContent. +func (v *InterfaceListOfListOfListsFieldWithPointerVideo) GetId() *testutil.ID { return v.Id } + +// GetName is a part of, and documented with, the interface InterfaceListOfListOfListsFieldWithPointerContent. +func (v *InterfaceListOfListOfListsFieldWithPointerVideo) GetName() *string { return v.Name } + func (v *InterfaceListOfListOfListsFieldWithPointerTopic) implementsGraphQLInterfaceInterfaceListOfListOfListsFieldWithPointerContent() { } +// GetTypename is a part of, and documented with, the interface InterfaceListOfListOfListsFieldWithPointerContent. +func (v *InterfaceListOfListOfListsFieldWithPointerTopic) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface InterfaceListOfListOfListsFieldWithPointerContent. +func (v *InterfaceListOfListOfListsFieldWithPointerTopic) GetId() *testutil.ID { return v.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" { return nil diff --git a/generate/testdata/snapshots/TestGenerate-InterfaceNesting.graphql-InterfaceNesting.graphql.go b/generate/testdata/snapshots/TestGenerate-InterfaceNesting.graphql-InterfaceNesting.graphql.go index 6775e781..336bf1d3 100644 --- a/generate/testdata/snapshots/TestGenerate-InterfaceNesting.graphql-InterfaceNesting.graphql.go +++ b/generate/testdata/snapshots/TestGenerate-InterfaceNesting.graphql-InterfaceNesting.graphql.go @@ -59,130 +59,75 @@ func (v *InterfaceNestingRootTopic) UnmarshalJSON(b []byte) error { type InterfaceNestingRootTopicChildrenArticle struct { Typename string `json:"__typename"` // ID is the identifier of the content. - Id testutil.ID `json:"id"` - Parent InterfaceNestingRootTopicChildrenArticleParentTopic `json:"parent"` + Id testutil.ID `json:"id"` + Parent InterfaceNestingRootTopicChildrenParentTopic `json:"parent"` } -// InterfaceNestingRootTopicChildrenArticleParentTopic includes the requested fields of the GraphQL type Topic. -type InterfaceNestingRootTopicChildrenArticleParentTopic struct { - // ID is documented in the Content interface. - Id testutil.ID `json:"id"` - Children []InterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent `json:"-"` -} - -func (v *InterfaceNestingRootTopicChildrenArticleParentTopic) UnmarshalJSON(b []byte) error { - - type InterfaceNestingRootTopicChildrenArticleParentTopicWrapper InterfaceNestingRootTopicChildrenArticleParentTopic - - var firstPass struct { - *InterfaceNestingRootTopicChildrenArticleParentTopicWrapper - Children []json.RawMessage `json:"children"` - } - firstPass.InterfaceNestingRootTopicChildrenArticleParentTopicWrapper = (*InterfaceNestingRootTopicChildrenArticleParentTopicWrapper)(v) - - err := json.Unmarshal(b, &firstPass) - if err != nil { - return err - } - - { - target := &v.Children - raw := firstPass.Children - *target = make( - []InterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent, - len(raw)) - for i, raw := range raw { - target := &(*target)[i] - err = __unmarshalInterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent( - target, raw) - if err != nil { - return err - } - } - } - return nil -} - -// InterfaceNestingRootTopicChildrenArticleParentTopicChildrenArticle includes the requested fields of the GraphQL type Article. -type InterfaceNestingRootTopicChildrenArticleParentTopicChildrenArticle struct { - Typename string `json:"__typename"` - // ID is the identifier of the content. - Id testutil.ID `json:"id"` -} - -// InterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent includes the requested fields of the GraphQL type Content. +// InterfaceNestingRootTopicChildrenContent includes the requested fields of the GraphQL interface Content. +// +// InterfaceNestingRootTopicChildrenContent is implemented by the following types: +// InterfaceNestingRootTopicChildrenArticle +// InterfaceNestingRootTopicChildrenVideo +// InterfaceNestingRootTopicChildrenTopic +// // The GraphQL type's documentation follows. // // Content is implemented by various types like Article, Video, and Topic. -type InterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent interface { - implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent() +type InterfaceNestingRootTopicChildrenContent interface { + implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenContent() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string + // GetId returns the interface-field "id" from its implementation. + // The GraphQL interface field's documentation follows. + // + // ID is the identifier of the content. + GetId() testutil.ID + // GetParent returns the interface-field "parent" from its implementation. + GetParent() InterfaceNestingRootTopicChildrenParentTopic } -func (v *InterfaceNestingRootTopicChildrenArticleParentTopicChildrenArticle) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent() { -} -func (v *InterfaceNestingRootTopicChildrenArticleParentTopicChildrenVideo) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent() { -} -func (v *InterfaceNestingRootTopicChildrenArticleParentTopicChildrenTopic) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent() { +func (v *InterfaceNestingRootTopicChildrenArticle) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenContent() { } -func __unmarshalInterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent(v *InterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent, m json.RawMessage) error { - if string(m) == "null" { - return nil - } +// GetTypename is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenContent. +func (v *InterfaceNestingRootTopicChildrenArticle) GetTypename() string { return v.Typename } - var tn struct { - TypeName string `json:"__typename"` - } - err := json.Unmarshal(m, &tn) - if err != nil { - return err - } +// GetId is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenContent. +func (v *InterfaceNestingRootTopicChildrenArticle) GetId() testutil.ID { return v.Id } - switch tn.TypeName { - case "Article": - *v = new(InterfaceNestingRootTopicChildrenArticleParentTopicChildrenArticle) - return json.Unmarshal(m, *v) - case "Video": - *v = new(InterfaceNestingRootTopicChildrenArticleParentTopicChildrenVideo) - return json.Unmarshal(m, *v) - case "Topic": - *v = new(InterfaceNestingRootTopicChildrenArticleParentTopicChildrenTopic) - return json.Unmarshal(m, *v) - default: - return fmt.Errorf( - `Unexpected concrete type for InterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent: "%v"`, tn.TypeName) - } +// GetParent is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenContent. +func (v *InterfaceNestingRootTopicChildrenArticle) GetParent() InterfaceNestingRootTopicChildrenParentTopic { + return v.Parent } -// InterfaceNestingRootTopicChildrenArticleParentTopicChildrenTopic includes the requested fields of the GraphQL type Topic. -type InterfaceNestingRootTopicChildrenArticleParentTopicChildrenTopic struct { - Typename string `json:"__typename"` - // ID is the identifier of the content. - Id testutil.ID `json:"id"` +func (v *InterfaceNestingRootTopicChildrenVideo) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenContent() { } -// InterfaceNestingRootTopicChildrenArticleParentTopicChildrenVideo includes the requested fields of the GraphQL type Video. -type InterfaceNestingRootTopicChildrenArticleParentTopicChildrenVideo struct { - Typename string `json:"__typename"` - // ID is the identifier of the content. - Id testutil.ID `json:"id"` -} +// GetTypename is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenContent. +func (v *InterfaceNestingRootTopicChildrenVideo) GetTypename() string { return v.Typename } -// InterfaceNestingRootTopicChildrenContent includes the requested fields of the GraphQL type Content. -// The GraphQL type's documentation follows. -// -// Content is implemented by various types like Article, Video, and Topic. -type InterfaceNestingRootTopicChildrenContent interface { - implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenContent() -} +// GetId is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenContent. +func (v *InterfaceNestingRootTopicChildrenVideo) GetId() testutil.ID { return v.Id } -func (v *InterfaceNestingRootTopicChildrenArticle) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenContent() { -} -func (v *InterfaceNestingRootTopicChildrenVideo) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenContent() { +// GetParent is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenContent. +func (v *InterfaceNestingRootTopicChildrenVideo) GetParent() InterfaceNestingRootTopicChildrenParentTopic { + return v.Parent } + func (v *InterfaceNestingRootTopicChildrenTopic) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenContent() { } +// GetTypename is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenContent. +func (v *InterfaceNestingRootTopicChildrenTopic) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenContent. +func (v *InterfaceNestingRootTopicChildrenTopic) GetId() testutil.ID { return v.Id } + +// GetParent is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenContent. +func (v *InterfaceNestingRootTopicChildrenTopic) GetParent() InterfaceNestingRootTopicChildrenParentTopic { + return v.Parent +} + func __unmarshalInterfaceNestingRootTopicChildrenContent(v *InterfaceNestingRootTopicChildrenContent, m json.RawMessage) error { if string(m) == "null" { return nil @@ -212,30 +157,22 @@ func __unmarshalInterfaceNestingRootTopicChildrenContent(v *InterfaceNestingRoot } } -// InterfaceNestingRootTopicChildrenTopic includes the requested fields of the GraphQL type Topic. -type InterfaceNestingRootTopicChildrenTopic struct { - Typename string `json:"__typename"` - // ID is the identifier of the content. - Id testutil.ID `json:"id"` - Parent InterfaceNestingRootTopicChildrenTopicParentTopic `json:"parent"` -} - -// InterfaceNestingRootTopicChildrenTopicParentTopic includes the requested fields of the GraphQL type Topic. -type InterfaceNestingRootTopicChildrenTopicParentTopic struct { +// InterfaceNestingRootTopicChildrenParentTopic includes the requested fields of the GraphQL type Topic. +type InterfaceNestingRootTopicChildrenParentTopic struct { // ID is documented in the Content interface. - Id testutil.ID `json:"id"` - Children []InterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent `json:"-"` + Id testutil.ID `json:"id"` + Children []InterfaceNestingRootTopicChildrenParentTopicChildrenContent `json:"-"` } -func (v *InterfaceNestingRootTopicChildrenTopicParentTopic) UnmarshalJSON(b []byte) error { +func (v *InterfaceNestingRootTopicChildrenParentTopic) UnmarshalJSON(b []byte) error { - type InterfaceNestingRootTopicChildrenTopicParentTopicWrapper InterfaceNestingRootTopicChildrenTopicParentTopic + type InterfaceNestingRootTopicChildrenParentTopicWrapper InterfaceNestingRootTopicChildrenParentTopic var firstPass struct { - *InterfaceNestingRootTopicChildrenTopicParentTopicWrapper + *InterfaceNestingRootTopicChildrenParentTopicWrapper Children []json.RawMessage `json:"children"` } - firstPass.InterfaceNestingRootTopicChildrenTopicParentTopicWrapper = (*InterfaceNestingRootTopicChildrenTopicParentTopicWrapper)(v) + firstPass.InterfaceNestingRootTopicChildrenParentTopicWrapper = (*InterfaceNestingRootTopicChildrenParentTopicWrapper)(v) err := json.Unmarshal(b, &firstPass) if err != nil { @@ -246,11 +183,11 @@ func (v *InterfaceNestingRootTopicChildrenTopicParentTopic) UnmarshalJSON(b []by target := &v.Children raw := firstPass.Children *target = make( - []InterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent, + []InterfaceNestingRootTopicChildrenParentTopicChildrenContent, len(raw)) for i, raw := range raw { target := &(*target)[i] - err = __unmarshalInterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent( + err = __unmarshalInterfaceNestingRootTopicChildrenParentTopicChildrenContent( target, raw) if err != nil { return err @@ -260,142 +197,70 @@ func (v *InterfaceNestingRootTopicChildrenTopicParentTopic) UnmarshalJSON(b []by return nil } -// InterfaceNestingRootTopicChildrenTopicParentTopicChildrenArticle includes the requested fields of the GraphQL type Article. -type InterfaceNestingRootTopicChildrenTopicParentTopicChildrenArticle struct { +// InterfaceNestingRootTopicChildrenParentTopicChildrenArticle includes the requested fields of the GraphQL type Article. +type InterfaceNestingRootTopicChildrenParentTopicChildrenArticle struct { Typename string `json:"__typename"` // ID is the identifier of the content. Id testutil.ID `json:"id"` } -// InterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent includes the requested fields of the GraphQL type Content. +// InterfaceNestingRootTopicChildrenParentTopicChildrenContent includes the requested fields of the GraphQL interface Content. +// +// InterfaceNestingRootTopicChildrenParentTopicChildrenContent is implemented by the following types: +// InterfaceNestingRootTopicChildrenParentTopicChildrenArticle +// InterfaceNestingRootTopicChildrenParentTopicChildrenVideo +// InterfaceNestingRootTopicChildrenParentTopicChildrenTopic +// // The GraphQL type's documentation follows. // // Content is implemented by various types like Article, Video, and Topic. -type InterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent interface { - implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent() +type InterfaceNestingRootTopicChildrenParentTopicChildrenContent interface { + implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenParentTopicChildrenContent() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string + // GetId returns the interface-field "id" from its implementation. + // The GraphQL interface field's documentation follows. + // + // ID is the identifier of the content. + GetId() testutil.ID } -func (v *InterfaceNestingRootTopicChildrenTopicParentTopicChildrenArticle) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent() { -} -func (v *InterfaceNestingRootTopicChildrenTopicParentTopicChildrenVideo) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent() { +func (v *InterfaceNestingRootTopicChildrenParentTopicChildrenArticle) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenParentTopicChildrenContent() { } -func (v *InterfaceNestingRootTopicChildrenTopicParentTopicChildrenTopic) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent() { -} - -func __unmarshalInterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent(v *InterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent, m json.RawMessage) error { - if string(m) == "null" { - return nil - } - var tn struct { - TypeName string `json:"__typename"` - } - err := json.Unmarshal(m, &tn) - if err != nil { - return err - } - - switch tn.TypeName { - case "Article": - *v = new(InterfaceNestingRootTopicChildrenTopicParentTopicChildrenArticle) - return json.Unmarshal(m, *v) - case "Video": - *v = new(InterfaceNestingRootTopicChildrenTopicParentTopicChildrenVideo) - return json.Unmarshal(m, *v) - case "Topic": - *v = new(InterfaceNestingRootTopicChildrenTopicParentTopicChildrenTopic) - return json.Unmarshal(m, *v) - default: - return fmt.Errorf( - `Unexpected concrete type for InterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent: "%v"`, tn.TypeName) - } -} - -// InterfaceNestingRootTopicChildrenTopicParentTopicChildrenTopic includes the requested fields of the GraphQL type Topic. -type InterfaceNestingRootTopicChildrenTopicParentTopicChildrenTopic struct { - Typename string `json:"__typename"` - // ID is the identifier of the content. - Id testutil.ID `json:"id"` +// GetTypename is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenParentTopicChildrenContent. +func (v *InterfaceNestingRootTopicChildrenParentTopicChildrenArticle) GetTypename() string { + return v.Typename } -// InterfaceNestingRootTopicChildrenTopicParentTopicChildrenVideo includes the requested fields of the GraphQL type Video. -type InterfaceNestingRootTopicChildrenTopicParentTopicChildrenVideo struct { - Typename string `json:"__typename"` - // ID is the identifier of the content. - Id testutil.ID `json:"id"` +// GetId is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenParentTopicChildrenContent. +func (v *InterfaceNestingRootTopicChildrenParentTopicChildrenArticle) GetId() testutil.ID { + return v.Id } -// InterfaceNestingRootTopicChildrenVideo includes the requested fields of the GraphQL type Video. -type InterfaceNestingRootTopicChildrenVideo struct { - Typename string `json:"__typename"` - // ID is the identifier of the content. - Id testutil.ID `json:"id"` - Parent InterfaceNestingRootTopicChildrenVideoParentTopic `json:"parent"` +func (v *InterfaceNestingRootTopicChildrenParentTopicChildrenVideo) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenParentTopicChildrenContent() { } -// InterfaceNestingRootTopicChildrenVideoParentTopic includes the requested fields of the GraphQL type Topic. -type InterfaceNestingRootTopicChildrenVideoParentTopic struct { - // ID is documented in the Content interface. - Id testutil.ID `json:"id"` - Children []InterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent `json:"-"` +// GetTypename is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenParentTopicChildrenContent. +func (v *InterfaceNestingRootTopicChildrenParentTopicChildrenVideo) GetTypename() string { + return v.Typename } -func (v *InterfaceNestingRootTopicChildrenVideoParentTopic) UnmarshalJSON(b []byte) error { - - type InterfaceNestingRootTopicChildrenVideoParentTopicWrapper InterfaceNestingRootTopicChildrenVideoParentTopic +// GetId is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenParentTopicChildrenContent. +func (v *InterfaceNestingRootTopicChildrenParentTopicChildrenVideo) GetId() testutil.ID { return v.Id } - var firstPass struct { - *InterfaceNestingRootTopicChildrenVideoParentTopicWrapper - Children []json.RawMessage `json:"children"` - } - firstPass.InterfaceNestingRootTopicChildrenVideoParentTopicWrapper = (*InterfaceNestingRootTopicChildrenVideoParentTopicWrapper)(v) - - err := json.Unmarshal(b, &firstPass) - if err != nil { - return err - } - - { - target := &v.Children - raw := firstPass.Children - *target = make( - []InterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent, - len(raw)) - for i, raw := range raw { - target := &(*target)[i] - err = __unmarshalInterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent( - target, raw) - if err != nil { - return err - } - } - } - return nil -} - -// InterfaceNestingRootTopicChildrenVideoParentTopicChildrenArticle includes the requested fields of the GraphQL type Article. -type InterfaceNestingRootTopicChildrenVideoParentTopicChildrenArticle struct { - Typename string `json:"__typename"` - // ID is the identifier of the content. - Id testutil.ID `json:"id"` +func (v *InterfaceNestingRootTopicChildrenParentTopicChildrenTopic) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenParentTopicChildrenContent() { } -// InterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent includes the requested fields of the GraphQL type Content. -// The GraphQL type's documentation follows. -// -// Content is implemented by various types like Article, Video, and Topic. -type InterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent interface { - implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent() +// GetTypename is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenParentTopicChildrenContent. +func (v *InterfaceNestingRootTopicChildrenParentTopicChildrenTopic) GetTypename() string { + return v.Typename } -func (v *InterfaceNestingRootTopicChildrenVideoParentTopicChildrenArticle) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent() { -} -func (v *InterfaceNestingRootTopicChildrenVideoParentTopicChildrenVideo) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent() { -} -func (v *InterfaceNestingRootTopicChildrenVideoParentTopicChildrenTopic) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent() { -} +// GetId is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenParentTopicChildrenContent. +func (v *InterfaceNestingRootTopicChildrenParentTopicChildrenTopic) GetId() testutil.ID { return v.Id } -func __unmarshalInterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent(v *InterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent, m json.RawMessage) error { +func __unmarshalInterfaceNestingRootTopicChildrenParentTopicChildrenContent(v *InterfaceNestingRootTopicChildrenParentTopicChildrenContent, m json.RawMessage) error { if string(m) == "null" { return nil } @@ -410,34 +275,50 @@ func __unmarshalInterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent switch tn.TypeName { case "Article": - *v = new(InterfaceNestingRootTopicChildrenVideoParentTopicChildrenArticle) + *v = new(InterfaceNestingRootTopicChildrenParentTopicChildrenArticle) return json.Unmarshal(m, *v) case "Video": - *v = new(InterfaceNestingRootTopicChildrenVideoParentTopicChildrenVideo) + *v = new(InterfaceNestingRootTopicChildrenParentTopicChildrenVideo) return json.Unmarshal(m, *v) case "Topic": - *v = new(InterfaceNestingRootTopicChildrenVideoParentTopicChildrenTopic) + *v = new(InterfaceNestingRootTopicChildrenParentTopicChildrenTopic) return json.Unmarshal(m, *v) default: return fmt.Errorf( - `Unexpected concrete type for InterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent: "%v"`, tn.TypeName) + `Unexpected concrete type for InterfaceNestingRootTopicChildrenParentTopicChildrenContent: "%v"`, tn.TypeName) } } -// InterfaceNestingRootTopicChildrenVideoParentTopicChildrenTopic includes the requested fields of the GraphQL type Topic. -type InterfaceNestingRootTopicChildrenVideoParentTopicChildrenTopic struct { +// InterfaceNestingRootTopicChildrenParentTopicChildrenTopic includes the requested fields of the GraphQL type Topic. +type InterfaceNestingRootTopicChildrenParentTopicChildrenTopic struct { Typename string `json:"__typename"` // ID is the identifier of the content. Id testutil.ID `json:"id"` } -// InterfaceNestingRootTopicChildrenVideoParentTopicChildrenVideo includes the requested fields of the GraphQL type Video. -type InterfaceNestingRootTopicChildrenVideoParentTopicChildrenVideo struct { +// InterfaceNestingRootTopicChildrenParentTopicChildrenVideo includes the requested fields of the GraphQL type Video. +type InterfaceNestingRootTopicChildrenParentTopicChildrenVideo struct { Typename string `json:"__typename"` // ID is the identifier of the content. Id testutil.ID `json:"id"` } +// InterfaceNestingRootTopicChildrenTopic includes the requested fields of the GraphQL type Topic. +type InterfaceNestingRootTopicChildrenTopic struct { + Typename string `json:"__typename"` + // ID is the identifier of the content. + Id testutil.ID `json:"id"` + Parent InterfaceNestingRootTopicChildrenParentTopic `json:"parent"` +} + +// InterfaceNestingRootTopicChildrenVideo includes the requested fields of the GraphQL type Video. +type InterfaceNestingRootTopicChildrenVideo struct { + Typename string `json:"__typename"` + // ID is the identifier of the content. + Id testutil.ID `json:"id"` + Parent InterfaceNestingRootTopicChildrenParentTopic `json:"parent"` +} + func InterfaceNesting( client graphql.Client, ) (*InterfaceNestingResponse, error) { diff --git a/generate/testdata/snapshots/TestGenerate-InterfaceNoFragments.graphql-InterfaceNoFragments.graphql.go b/generate/testdata/snapshots/TestGenerate-InterfaceNoFragments.graphql-InterfaceNoFragments.graphql.go index ac074d3b..4880e101 100644 --- a/generate/testdata/snapshots/TestGenerate-InterfaceNoFragments.graphql-InterfaceNoFragments.graphql.go +++ b/generate/testdata/snapshots/TestGenerate-InterfaceNoFragments.graphql-InterfaceNoFragments.graphql.go @@ -18,21 +18,65 @@ type InterfaceNoFragmentsQueryRandomItemArticle struct { Name string `json:"name"` } -// InterfaceNoFragmentsQueryRandomItemContent includes the requested fields of the GraphQL type Content. +// InterfaceNoFragmentsQueryRandomItemContent includes the requested fields of the GraphQL interface Content. +// +// InterfaceNoFragmentsQueryRandomItemContent is implemented by the following types: +// InterfaceNoFragmentsQueryRandomItemArticle +// InterfaceNoFragmentsQueryRandomItemVideo +// InterfaceNoFragmentsQueryRandomItemTopic +// // The GraphQL type's documentation follows. // // Content is implemented by various types like Article, Video, and Topic. type InterfaceNoFragmentsQueryRandomItemContent interface { implementsGraphQLInterfaceInterfaceNoFragmentsQueryRandomItemContent() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string + // GetId returns the interface-field "id" from its implementation. + // The GraphQL interface field's documentation follows. + // + // ID is the identifier of the content. + GetId() testutil.ID + // GetName returns the interface-field "name" from its implementation. + GetName() string } func (v *InterfaceNoFragmentsQueryRandomItemArticle) implementsGraphQLInterfaceInterfaceNoFragmentsQueryRandomItemContent() { } + +// GetTypename is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemContent. +func (v *InterfaceNoFragmentsQueryRandomItemArticle) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemContent. +func (v *InterfaceNoFragmentsQueryRandomItemArticle) GetId() testutil.ID { return v.Id } + +// GetName is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemContent. +func (v *InterfaceNoFragmentsQueryRandomItemArticle) GetName() string { return v.Name } + func (v *InterfaceNoFragmentsQueryRandomItemVideo) implementsGraphQLInterfaceInterfaceNoFragmentsQueryRandomItemContent() { } + +// GetTypename is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemContent. +func (v *InterfaceNoFragmentsQueryRandomItemVideo) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemContent. +func (v *InterfaceNoFragmentsQueryRandomItemVideo) GetId() testutil.ID { return v.Id } + +// GetName is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemContent. +func (v *InterfaceNoFragmentsQueryRandomItemVideo) GetName() string { return v.Name } + func (v *InterfaceNoFragmentsQueryRandomItemTopic) implementsGraphQLInterfaceInterfaceNoFragmentsQueryRandomItemContent() { } +// GetTypename is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemContent. +func (v *InterfaceNoFragmentsQueryRandomItemTopic) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemContent. +func (v *InterfaceNoFragmentsQueryRandomItemTopic) GetId() testutil.ID { return v.Id } + +// 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" { return nil @@ -86,21 +130,71 @@ type InterfaceNoFragmentsQueryRandomItemWithTypeNameArticle struct { Name string `json:"name"` } -// InterfaceNoFragmentsQueryRandomItemWithTypeNameContent includes the requested fields of the GraphQL type Content. +// InterfaceNoFragmentsQueryRandomItemWithTypeNameContent includes the requested fields of the GraphQL interface Content. +// +// InterfaceNoFragmentsQueryRandomItemWithTypeNameContent is implemented by the following types: +// InterfaceNoFragmentsQueryRandomItemWithTypeNameArticle +// InterfaceNoFragmentsQueryRandomItemWithTypeNameVideo +// InterfaceNoFragmentsQueryRandomItemWithTypeNameTopic +// // The GraphQL type's documentation follows. // // Content is implemented by various types like Article, Video, and Topic. type InterfaceNoFragmentsQueryRandomItemWithTypeNameContent interface { implementsGraphQLInterfaceInterfaceNoFragmentsQueryRandomItemWithTypeNameContent() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string + // GetId returns the interface-field "id" from its implementation. + // The GraphQL interface field's documentation follows. + // + // ID is the identifier of the content. + GetId() testutil.ID + // GetName returns the interface-field "name" from its implementation. + GetName() string } func (v *InterfaceNoFragmentsQueryRandomItemWithTypeNameArticle) implementsGraphQLInterfaceInterfaceNoFragmentsQueryRandomItemWithTypeNameContent() { } + +// GetTypename is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemWithTypeNameContent. +func (v *InterfaceNoFragmentsQueryRandomItemWithTypeNameArticle) GetTypename() string { + return v.Typename +} + +// GetId is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemWithTypeNameContent. +func (v *InterfaceNoFragmentsQueryRandomItemWithTypeNameArticle) GetId() testutil.ID { return v.Id } + +// GetName is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemWithTypeNameContent. +func (v *InterfaceNoFragmentsQueryRandomItemWithTypeNameArticle) GetName() string { return v.Name } + func (v *InterfaceNoFragmentsQueryRandomItemWithTypeNameVideo) implementsGraphQLInterfaceInterfaceNoFragmentsQueryRandomItemWithTypeNameContent() { } + +// GetTypename is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemWithTypeNameContent. +func (v *InterfaceNoFragmentsQueryRandomItemWithTypeNameVideo) GetTypename() string { + return v.Typename +} + +// GetId is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemWithTypeNameContent. +func (v *InterfaceNoFragmentsQueryRandomItemWithTypeNameVideo) GetId() testutil.ID { return v.Id } + +// GetName is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemWithTypeNameContent. +func (v *InterfaceNoFragmentsQueryRandomItemWithTypeNameVideo) GetName() string { return v.Name } + func (v *InterfaceNoFragmentsQueryRandomItemWithTypeNameTopic) implementsGraphQLInterfaceInterfaceNoFragmentsQueryRandomItemWithTypeNameContent() { } +// GetTypename is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemWithTypeNameContent. +func (v *InterfaceNoFragmentsQueryRandomItemWithTypeNameTopic) GetTypename() string { + return v.Typename +} + +// GetId is a part of, and documented with, the interface InterfaceNoFragmentsQueryRandomItemWithTypeNameContent. +func (v *InterfaceNoFragmentsQueryRandomItemWithTypeNameTopic) GetId() testutil.ID { return v.Id } + +// 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" { return nil @@ -216,21 +310,65 @@ type InterfaceNoFragmentsQueryWithPointerArticle struct { Name *string `json:"name"` } -// InterfaceNoFragmentsQueryWithPointerContent includes the requested fields of the GraphQL type Content. +// InterfaceNoFragmentsQueryWithPointerContent includes the requested fields of the GraphQL interface Content. +// +// InterfaceNoFragmentsQueryWithPointerContent is implemented by the following types: +// InterfaceNoFragmentsQueryWithPointerArticle +// InterfaceNoFragmentsQueryWithPointerVideo +// InterfaceNoFragmentsQueryWithPointerTopic +// // The GraphQL type's documentation follows. // // Content is implemented by various types like Article, Video, and Topic. type InterfaceNoFragmentsQueryWithPointerContent interface { implementsGraphQLInterfaceInterfaceNoFragmentsQueryWithPointerContent() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string + // GetId returns the interface-field "id" from its implementation. + // The GraphQL interface field's documentation follows. + // + // ID is the identifier of the content. + GetId() *testutil.ID + // GetName returns the interface-field "name" from its implementation. + GetName() *string } func (v *InterfaceNoFragmentsQueryWithPointerArticle) implementsGraphQLInterfaceInterfaceNoFragmentsQueryWithPointerContent() { } + +// GetTypename is a part of, and documented with, the interface InterfaceNoFragmentsQueryWithPointerContent. +func (v *InterfaceNoFragmentsQueryWithPointerArticle) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface InterfaceNoFragmentsQueryWithPointerContent. +func (v *InterfaceNoFragmentsQueryWithPointerArticle) GetId() *testutil.ID { return v.Id } + +// GetName is a part of, and documented with, the interface InterfaceNoFragmentsQueryWithPointerContent. +func (v *InterfaceNoFragmentsQueryWithPointerArticle) GetName() *string { return v.Name } + func (v *InterfaceNoFragmentsQueryWithPointerVideo) implementsGraphQLInterfaceInterfaceNoFragmentsQueryWithPointerContent() { } + +// GetTypename is a part of, and documented with, the interface InterfaceNoFragmentsQueryWithPointerContent. +func (v *InterfaceNoFragmentsQueryWithPointerVideo) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface InterfaceNoFragmentsQueryWithPointerContent. +func (v *InterfaceNoFragmentsQueryWithPointerVideo) GetId() *testutil.ID { return v.Id } + +// GetName is a part of, and documented with, the interface InterfaceNoFragmentsQueryWithPointerContent. +func (v *InterfaceNoFragmentsQueryWithPointerVideo) GetName() *string { return v.Name } + func (v *InterfaceNoFragmentsQueryWithPointerTopic) implementsGraphQLInterfaceInterfaceNoFragmentsQueryWithPointerContent() { } +// GetTypename is a part of, and documented with, the interface InterfaceNoFragmentsQueryWithPointerContent. +func (v *InterfaceNoFragmentsQueryWithPointerTopic) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface InterfaceNoFragmentsQueryWithPointerContent. +func (v *InterfaceNoFragmentsQueryWithPointerTopic) GetId() *testutil.ID { return v.Id } + +// 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" { return nil diff --git a/generate/testdata/snapshots/TestGenerate-UnionNoFragments.graphql-UnionNoFragments.graphql.go b/generate/testdata/snapshots/TestGenerate-UnionNoFragments.graphql-UnionNoFragments.graphql.go index ac214bee..43fe75b1 100644 --- a/generate/testdata/snapshots/TestGenerate-UnionNoFragments.graphql-UnionNoFragments.graphql.go +++ b/generate/testdata/snapshots/TestGenerate-UnionNoFragments.graphql-UnionNoFragments.graphql.go @@ -14,19 +14,33 @@ type UnionNoFragmentsQueryRandomLeafArticle struct { Typename string `json:"__typename"` } -// UnionNoFragmentsQueryRandomLeafLeafContent includes the requested fields of the GraphQL type LeafContent. +// UnionNoFragmentsQueryRandomLeafLeafContent includes the requested fields of the GraphQL interface LeafContent. +// +// UnionNoFragmentsQueryRandomLeafLeafContent is implemented by the following types: +// UnionNoFragmentsQueryRandomLeafArticle +// UnionNoFragmentsQueryRandomLeafVideo +// // The GraphQL type's documentation follows. // // LeafContent represents content items that can't have child-nodes. type UnionNoFragmentsQueryRandomLeafLeafContent interface { implementsGraphQLInterfaceUnionNoFragmentsQueryRandomLeafLeafContent() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string } func (v *UnionNoFragmentsQueryRandomLeafArticle) implementsGraphQLInterfaceUnionNoFragmentsQueryRandomLeafLeafContent() { } + +// GetTypename is a part of, and documented with, the interface UnionNoFragmentsQueryRandomLeafLeafContent. +func (v *UnionNoFragmentsQueryRandomLeafArticle) GetTypename() string { return v.Typename } + func (v *UnionNoFragmentsQueryRandomLeafVideo) implementsGraphQLInterfaceUnionNoFragmentsQueryRandomLeafLeafContent() { } +// 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" { return nil diff --git a/generate/traverse.go b/generate/traverse.go index 83acee2a..3ec1226b 100644 --- a/generate/traverse.go +++ b/generate/traverse.go @@ -250,6 +250,7 @@ func (g *generator) convertDefinition( GoName: goName, GoType: fieldGoType, JSONName: field.Name, + GraphQLName: field.Name, Description: field.Description, } } @@ -265,19 +266,52 @@ func (g *generator) convertDefinition( GoName: name, Description: def.Description, GraphQLName: def.Name, + SharedFields: make([]*goStructField, 0, len(selectionSet)), Implementations: make([]*goStructType, len(implementationTypes)), } g.typeMap[name] = goType + // TODO(benkraft): This sorta-duplicates what we'll do in each + // implementation when it traverses the fields. But they'll differ + // more once we support fragments; at that point we should figure out + // how to refactor. + for _, selection := range selectionSet { + field, ok := selection.(*ast.Field) + if !ok { // fragment/interface, not a shared field + continue + } + _, fieldDirective, err := g.parsePrecedingComment(field, field.GetPosition()) + if err != nil { + return nil, err + } + fieldOptions := queryOptions.merge(fieldDirective) + + goField, err := g.convertField(namePrefix, field, fieldOptions, queryOptions) + if err != nil { + return nil, err + } + goType.SharedFields = append(goType.SharedFields, goField) + } + for i, implDef := range implementationTypes { - implName, implNamePrefix := g.typeName(namePrefix, implDef) + // Note for shared fields we propagate forward the interface's + // name-prefix: that is, the implementations will have fields with + // types like + // MyInterfaceMyFieldMyType + // not + // MyInterfaceMyImplMyFieldMyType + // ^^^^^^ + // In particular, this means that the Go type of MyField will be + // the same across all the implementations; this is important so + // that we can write a method GetMyField() that returns it! + implName, _ := g.typeName(namePrefix, implDef) // TODO(benkraft): In principle we should skip generating a Go // field for __typename each of these impl-defs if you didn't // request it (and it was automatically added by // preprocessQueryDocument). But in practice it doesn't really // hurt, and would be extra work to avoid, so we just leave it. implTyp, err := g.convertDefinition( - implName, implNamePrefix, implDef, pos, selectionSet, queryOptions) + implName, namePrefix, implDef, pos, selectionSet, queryOptions) if err != nil { return nil, err } @@ -357,6 +391,7 @@ func (g *generator) convertField( GoName: goName, GoType: fieldGoType, JSONName: field.Alias, + GraphQLName: field.Name, Description: field.Definition.Description, }, nil } diff --git a/generate/types.go b/generate/types.go index bb4563d8..340e668b 100644 --- a/generate/types.go +++ b/generate/types.go @@ -113,7 +113,8 @@ type goStructType struct { type goStructField struct { GoName string GoType goType - JSONName string + JSONName string // i.e. the field's alias in this query + GraphQLName string // i.e. the field's name in its type-def Description string } @@ -125,7 +126,20 @@ func isAbstract(typ goType) bool { func (typ *goStructType) WriteDefinition(w io.Writer, g *generator) error { description := typ.Description if typ.Incomplete { - description = incompleteTypeDescription(typ.GoName, typ.GraphQLName, typ.Description) + // For types where we only have some fields, note that, along with + // the GraphQL documentation (if any). We don't want to just use + // the GraphQL documentation, since it may refer to fields we + // haven't selected, say. + prefix := fmt.Sprintf( + "%v includes the requested fields of the GraphQL type %v.", + typ.GoName, typ.GraphQLName) + if description != "" { + description = fmt.Sprintf( + "%v\nThe GraphQL type's documentation follows.\n\n%v", + prefix, description) + } else { + description = prefix + } } writeDescription(w, description) @@ -181,28 +195,76 @@ func (typ *goStructType) AbstractFields() []*goStructField { // goInterfaceType represents a Go interface type, used to represent a GraphQL // interface or union type. type goInterfaceType struct { - GoName string - Description string - GraphQLName string + GoName string + Description string + GraphQLName string + // Fields shared by all the interface's implementations; + // we'll generate getter methods for each. + SharedFields []*goStructField Implementations []*goStructType } func (typ *goInterfaceType) WriteDefinition(w io.Writer, g *generator) error { - // TODO(benkraft): also mention the list of implementations. - description := incompleteTypeDescription(typ.GoName, typ.GraphQLName, typ.Description) + goTypeNames := make([]string, len(typ.Implementations)) + for i, impl := range typ.Implementations { + goTypeNames[i] = impl.Reference() + } + + description := fmt.Sprintf( + "%v includes the requested fields of the GraphQL interface %v.\n\n"+ + "%v is implemented by the following types:\n\t%v", + typ.GoName, typ.GraphQLName, typ.GoName, strings.Join(goTypeNames, "\n\t")) + if description != "" { + description = fmt.Sprintf( + "%v\n\nThe GraphQL type's documentation follows.\n\n%v", + description, typ.Description) + } writeDescription(w, description) // Write the interface. fmt.Fprintf(w, "type %s interface {\n", typ.GoName) implementsMethodName := fmt.Sprintf("implementsGraphQLInterface%v", typ.GoName) - // TODO(benkraft): Also write GetX() accessor methods for fields of the interface fmt.Fprintf(w, "\t%s()\n", implementsMethodName) + for _, sharedField := range typ.SharedFields { + methodName := "Get" + sharedField.GoName + description := "" + if sharedField.GraphQLName == "__typename" { + description = fmt.Sprintf( + "%s returns the receiver's concrete GraphQL type-name "+ + "(see interface doc for possible values).", methodName) + } else { + description = fmt.Sprintf( + `%s returns the interface-field "%s" from its implementation.`, + methodName, sharedField.GraphQLName) + if sharedField.Description != "" { + description = fmt.Sprintf( + "%s\nThe GraphQL interface field's documentation follows.\n\n%s", + description, sharedField.Description) + } + } + + writeDescription(w, description) + fmt.Fprintf(w, "\t%s() %s\n", methodName, sharedField.GoType.Reference()) + } fmt.Fprintf(w, "}\n") // Now, write out the implementations. for _, impl := range typ.Implementations { fmt.Fprintf(w, "func (v *%s) %s() {}\n", impl.Reference(), implementsMethodName) + for _, sharedField := range typ.SharedFields { + description := fmt.Sprintf( + "Get%s is a part of, and documented with, the interface %s.", + sharedField.GoName, typ.GoName) + writeDescription(w, description) + // In principle we should find the corresponding field of the + // implementation and use its name in `v.`. In practice, + // they're always the same. + fmt.Fprintf(w, "func (v *%s) Get%s() %s { return v.%s }\n", + impl.Reference(), sharedField.GoName, + sharedField.GoType.Reference(), sharedField.GoName) + } + fmt.Fprintf(w, "\n") // blank line between each type's implementations } // Finally, write the unmarshal-helper, which will be called by struct @@ -245,22 +307,6 @@ func (typ *goEnumType) IsPointer() bool { return false } func (typ *goStructType) IsPointer() bool { return false } func (typ *goInterfaceType) IsPointer() bool { return false } -func incompleteTypeDescription(goName, graphQLName, description string) string { - // For types where we only have some fields, note that, along with - // the GraphQL documentation (if any). We don't want to just use - // the GraphQL documentation, since it may refer to fields we - // haven't selected, say. - prefix := fmt.Sprintf( - "%v includes the requested fields of the GraphQL type %v.", - goName, graphQLName) - if description != "" { - return fmt.Sprintf( - "%v\nThe GraphQL type's documentation follows.\n\n%v", - prefix, description) - } - return prefix -} - func writeDescription(w io.Writer, desc string) { if desc != "" { for _, line := range strings.Split(desc, "\n") { diff --git a/internal/integration/generated.go b/internal/integration/generated.go index ed96b2f8..863a8638 100644 --- a/internal/integration/generated.go +++ b/internal/integration/generated.go @@ -17,16 +17,49 @@ type queryWithInterfaceListFieldBeingsAnimal struct { Name string `json:"name"` } -// queryWithInterfaceListFieldBeingsBeing includes the requested fields of the GraphQL type Being. +// queryWithInterfaceListFieldBeingsBeing includes the requested fields of the GraphQL interface Being. +// +// queryWithInterfaceListFieldBeingsBeing is implemented by the following types: +// queryWithInterfaceListFieldBeingsUser +// queryWithInterfaceListFieldBeingsAnimal +// +// The GraphQL type's documentation follows. +// +// type queryWithInterfaceListFieldBeingsBeing interface { implementsGraphQLInterfacequeryWithInterfaceListFieldBeingsBeing() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string + // GetId returns the interface-field "id" from its implementation. + GetId() string + // GetName returns the interface-field "name" from its implementation. + GetName() string } func (v *queryWithInterfaceListFieldBeingsUser) implementsGraphQLInterfacequeryWithInterfaceListFieldBeingsBeing() { } + +// GetTypename is a part of, and documented with, the interface queryWithInterfaceListFieldBeingsBeing. +func (v *queryWithInterfaceListFieldBeingsUser) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface queryWithInterfaceListFieldBeingsBeing. +func (v *queryWithInterfaceListFieldBeingsUser) GetId() string { return v.Id } + +// GetName is a part of, and documented with, the interface queryWithInterfaceListFieldBeingsBeing. +func (v *queryWithInterfaceListFieldBeingsUser) GetName() string { return v.Name } + func (v *queryWithInterfaceListFieldBeingsAnimal) implementsGraphQLInterfacequeryWithInterfaceListFieldBeingsBeing() { } +// GetTypename is a part of, and documented with, the interface queryWithInterfaceListFieldBeingsBeing. +func (v *queryWithInterfaceListFieldBeingsAnimal) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface queryWithInterfaceListFieldBeingsBeing. +func (v *queryWithInterfaceListFieldBeingsAnimal) GetId() string { return v.Id } + +// GetName is a part of, and documented with, the interface queryWithInterfaceListFieldBeingsBeing. +func (v *queryWithInterfaceListFieldBeingsAnimal) GetName() string { return v.Name } + func __unmarshalqueryWithInterfaceListFieldBeingsBeing(v *queryWithInterfaceListFieldBeingsBeing, m json.RawMessage) error { if string(m) == "null" { return nil @@ -98,16 +131,49 @@ func (v *queryWithInterfaceListFieldResponse) UnmarshalJSON(b []byte) error { return nil } -// queryWithInterfaceNoFragmentsBeing includes the requested fields of the GraphQL type Being. +// queryWithInterfaceNoFragmentsBeing includes the requested fields of the GraphQL interface Being. +// +// queryWithInterfaceNoFragmentsBeing is implemented by the following types: +// queryWithInterfaceNoFragmentsBeingUser +// queryWithInterfaceNoFragmentsBeingAnimal +// +// The GraphQL type's documentation follows. +// +// type queryWithInterfaceNoFragmentsBeing interface { implementsGraphQLInterfacequeryWithInterfaceNoFragmentsBeing() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string + // GetId returns the interface-field "id" from its implementation. + GetId() string + // GetName returns the interface-field "name" from its implementation. + GetName() string } func (v *queryWithInterfaceNoFragmentsBeingUser) implementsGraphQLInterfacequeryWithInterfaceNoFragmentsBeing() { } + +// GetTypename is a part of, and documented with, the interface queryWithInterfaceNoFragmentsBeing. +func (v *queryWithInterfaceNoFragmentsBeingUser) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface queryWithInterfaceNoFragmentsBeing. +func (v *queryWithInterfaceNoFragmentsBeingUser) GetId() string { return v.Id } + +// GetName is a part of, and documented with, the interface queryWithInterfaceNoFragmentsBeing. +func (v *queryWithInterfaceNoFragmentsBeingUser) GetName() string { return v.Name } + func (v *queryWithInterfaceNoFragmentsBeingAnimal) implementsGraphQLInterfacequeryWithInterfaceNoFragmentsBeing() { } +// GetTypename is a part of, and documented with, the interface queryWithInterfaceNoFragmentsBeing. +func (v *queryWithInterfaceNoFragmentsBeingAnimal) GetTypename() string { return v.Typename } + +// GetId is a part of, and documented with, the interface queryWithInterfaceNoFragmentsBeing. +func (v *queryWithInterfaceNoFragmentsBeingAnimal) GetId() string { return v.Id } + +// GetName is a part of, and documented with, the interface queryWithInterfaceNoFragmentsBeing. +func (v *queryWithInterfaceNoFragmentsBeingAnimal) GetName() string { return v.Name } + func __unmarshalqueryWithInterfaceNoFragmentsBeing(v *queryWithInterfaceNoFragmentsBeing, m json.RawMessage) error { if string(m) == "null" { return nil diff --git a/internal/integration/integration_test.go b/internal/integration/integration_test.go index a94ffa1d..f44ec001 100644 --- a/internal/integration/integration_test.go +++ b/internal/integration/integration_test.go @@ -71,9 +71,18 @@ func TestInterfaceNoFragments(t *testing.T) { resp, err := queryWithInterfaceNoFragments(ctx, client, "1") require.NoError(t, err) + // We should get the following response: + // me: User{Id: 1, Name: "Yours Truly"}, + // being: User{Id: 1, Name: "Yours Truly"}, + assert.Equal(t, "1", resp.Me.Id) assert.Equal(t, "Yours Truly", resp.Me.Name) + // Check fields both via interface and via type-assertion: + assert.Equal(t, "User", resp.Being.GetTypename()) + assert.Equal(t, "1", resp.Being.GetId()) + assert.Equal(t, "Yours Truly", resp.Being.GetName()) + user, ok := resp.Being.(*queryWithInterfaceNoFragmentsBeingUser) require.Truef(t, ok, "got %T, not User", resp.Being) assert.Equal(t, "1", user.Id) @@ -82,9 +91,17 @@ func TestInterfaceNoFragments(t *testing.T) { resp, err = queryWithInterfaceNoFragments(ctx, client, "3") require.NoError(t, err) + // We should get the following response: + // me: User{Id: 1, Name: "Yours Truly"}, + // being: Animal{Id: 3, Name: "Fido"}, + assert.Equal(t, "1", resp.Me.Id) assert.Equal(t, "Yours Truly", resp.Me.Name) + assert.Equal(t, "Animal", resp.Being.GetTypename()) + assert.Equal(t, "3", resp.Being.GetId()) + assert.Equal(t, "Fido", resp.Being.GetName()) + animal, ok := resp.Being.(*queryWithInterfaceNoFragmentsBeingAnimal) require.Truef(t, ok, "got %T, not Animal", resp.Being) assert.Equal(t, "3", animal.Id) @@ -93,6 +110,10 @@ func TestInterfaceNoFragments(t *testing.T) { resp, err = queryWithInterfaceNoFragments(ctx, client, "4757233945723") require.NoError(t, err) + // We should get the following response: + // me: User{Id: 1, Name: "Yours Truly"}, + // being: null + assert.Equal(t, "1", resp.Me.Id) assert.Equal(t, "Yours Truly", resp.Me.Name) @@ -116,11 +137,25 @@ func TestInterfaceListField(t *testing.T) { require.Len(t, resp.Beings, 3) + // We should get the following three beings: + // User{Id: 1, Name: "Yours Truly"}, + // Animal{Id: 3, Name: "Fido"}, + // null + + // Check fields both via interface and via type-assertion: + assert.Equal(t, "User", resp.Beings[0].GetTypename()) + assert.Equal(t, "1", resp.Beings[0].GetId()) + assert.Equal(t, "Yours Truly", resp.Beings[0].GetName()) + user, ok := resp.Beings[0].(*queryWithInterfaceListFieldBeingsUser) require.Truef(t, ok, "got %T, not User", resp.Beings[0]) assert.Equal(t, "1", user.Id) assert.Equal(t, "Yours Truly", user.Name) + assert.Equal(t, "Animal", resp.Beings[1].GetTypename()) + assert.Equal(t, "3", resp.Beings[1].GetId()) + assert.Equal(t, "Fido", resp.Beings[1].GetName()) + animal, ok := resp.Beings[1].(*queryWithInterfaceListFieldBeingsAnimal) require.Truef(t, ok, "got %T, not Animal", resp.Beings[1]) assert.Equal(t, "3", animal.Id)