Add support for interfaces, part 4: getter methods (#57)

## Summary:
Right now, if you make a query like `{ myInterface { field } }`, you
have to type-switch on all the possible implementations of `myInterface`
to get at `field`.  Now, we generate getter-methods (e.g. `GetField`),
to make that access easier.  Of course this only applies to shared
fields (which for now are the only ones, but once we support fragments
will no longer be).

This also includes a small change to the way we generate type-names for
interfaces: we no longer include the name of the concrete type in the
interface we propagate forward, so we generate
`MyInterfaceMyFieldMyType`, not `MyInterfaceMyImplMyFieldMyType`, in the
case where you have an interface `MyInterface` implemented by `MyImpl`
(and maybe other types) with field `myField: MyType`.  This is necessary
so the getter method returns a well-defined type, and also probably
convenient for calling code.  It will have to get a little bit more
complicated once we support fragments, where you could have two
implementing types with identically-named fields of different types, but
I think it'll be easiest to figure out how to deal with that when
implementing fragments.

While I was in the area, I added to the interface doc-comment a list of
the implementations.  (In GraphQL, we're guaranteed to know them all
assuming our schema is up to date.)

Issue: https://github.com/Khan/genqlient/issues/8

## Test plan:
make check


Author: benjaminjkraft

Reviewers: benjaminjkraft, dnerdy, aberkan, MiguelCastillo

Required Reviewers: 

Approved by: dnerdy

Checks:  Test (1.17),  Test (1.16),  Test (1.15),  Test (1.14),  Test (1.13),  Lint,  Test (1.17),  Test (1.16),  Test (1.15),  Test (1.14),  Test (1.13),  Lint

Pull request URL: https://github.com/Khan/genqlient/pull/57
This commit is contained in:
Ben Kraft
2021-08-25 12:02:18 -07:00
committed by GitHub
parent 65f9e90f2b
commit 8f9d1cf792
10 changed files with 750 additions and 289 deletions
+37 -2
View File
@@ -249,6 +249,7 @@ func (g *generator) convertDefinition(
GoName: goName, GoName: goName,
GoType: fieldGoType, GoType: fieldGoType,
JSONName: field.Name, JSONName: field.Name,
GraphQLName: field.Name,
Description: field.Description, Description: field.Description,
} }
} }
@@ -264,19 +265,52 @@ func (g *generator) convertDefinition(
GoName: name, GoName: name,
Description: def.Description, Description: def.Description,
GraphQLName: def.Name, GraphQLName: def.Name,
SharedFields: make([]*goStructField, 0, len(selectionSet)),
Implementations: make([]*goStructType, len(implementationTypes)), Implementations: make([]*goStructType, len(implementationTypes)),
} }
g.typeMap[name] = goType 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 { 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 // TODO(benkraft): In principle we should skip generating a Go
// field for __typename each of these impl-defs if you didn't // field for __typename each of these impl-defs if you didn't
// request it (and it was automatically added by // request it (and it was automatically added by
// preprocessQueryDocument). But in practice it doesn't really // preprocessQueryDocument). But in practice it doesn't really
// hurt, and would be extra work to avoid, so we just leave it. // hurt, and would be extra work to avoid, so we just leave it.
implTyp, err := g.convertDefinition( implTyp, err := g.convertDefinition(
implName, implNamePrefix, implDef, pos, selectionSet, queryOptions) implName, namePrefix, implDef, pos, selectionSet, queryOptions)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -356,6 +390,7 @@ func (g *generator) convertField(
GoName: goName, GoName: goName,
GoType: fieldGoType, GoType: fieldGoType,
JSONName: field.Alias, JSONName: field.Alias,
GraphQLName: field.Name,
Description: field.Definition.Description, Description: field.Definition.Description,
}, nil }, nil
} }
+10
View File
@@ -6,6 +6,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"runtime"
"strings" "strings"
"testing" "testing"
@@ -62,6 +63,15 @@ func TestGenerate(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
if strings.HasPrefix(runtime.Version(), "go1.13") &&
(sourceFilename == "InterfaceNesting.graphql" ||
sourceFilename == "InterfaceNoFragments.graphql") {
// gofmt on 1.13 formats this slightly differently.
// TODO(benkraft): Vendor in a specific version of gofmt,
// to use for all Go versions. (Maybe only for tests.)
t.Skip("skipping because go1.13 formats them differently")
}
for filename, content := range generated { for filename, content := range generated {
t.Run(filename, func(t *testing.T) { t.Run(filename, func(t *testing.T) {
testutil.Cupaloy.SnapshotT(t, string(content)) testutil.Cupaloy.SnapshotT(t, string(content))
@@ -65,21 +65,65 @@ type InterfaceListFieldRootTopicChildrenArticle struct {
Name string `json:"name"` 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. // The GraphQL type's documentation follows.
// //
// Content is implemented by various types like Article, Video, and Topic. // Content is implemented by various types like Article, Video, and Topic.
type InterfaceListFieldRootTopicChildrenContent interface { type InterfaceListFieldRootTopicChildrenContent interface {
implementsGraphQLInterfaceInterfaceListFieldRootTopicChildrenContent() 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() { 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() { 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() { 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 { func __unmarshalInterfaceListFieldRootTopicChildrenContent(v *InterfaceListFieldRootTopicChildrenContent, m json.RawMessage) error {
if string(m) == "null" { if string(m) == "null" {
return nil return nil
@@ -174,21 +218,65 @@ type InterfaceListFieldWithPointerTopicChildrenArticle struct {
Name string `json:"name"` 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. // The GraphQL type's documentation follows.
// //
// Content is implemented by various types like Article, Video, and Topic. // Content is implemented by various types like Article, Video, and Topic.
type InterfaceListFieldWithPointerTopicChildrenContent interface { type InterfaceListFieldWithPointerTopicChildrenContent interface {
implementsGraphQLInterfaceInterfaceListFieldWithPointerTopicChildrenContent() 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() { 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() { 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() { 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 { func __unmarshalInterfaceListFieldWithPointerTopicChildrenContent(v *InterfaceListFieldWithPointerTopicChildrenContent, m json.RawMessage) error {
if string(m) == "null" { if string(m) == "null" {
return nil return nil
@@ -10,21 +10,83 @@ import (
"github.com/Khan/genqlient/internal/testutil" "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. // The GraphQL type's documentation follows.
// //
// Content is implemented by various types like Article, Video, and Topic. // Content is implemented by various types like Article, Video, and Topic.
type InterfaceListOfListOfListsFieldListOfListsOfListsOfContent interface { type InterfaceListOfListOfListsFieldListOfListsOfListsOfContent interface {
implementsGraphQLInterfaceInterfaceListOfListOfListsFieldListOfListsOfListsOfContent() 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() { 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() { 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() { 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 { func __unmarshalInterfaceListOfListOfListsFieldListOfListsOfListsOfContent(v *InterfaceListOfListOfListsFieldListOfListsOfListsOfContent, m json.RawMessage) error {
if string(m) == "null" { if string(m) == "null" {
return nil return nil
@@ -166,21 +228,65 @@ type InterfaceListOfListOfListsFieldWithPointerArticle struct {
Name *string `json:"name"` 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. // The GraphQL type's documentation follows.
// //
// Content is implemented by various types like Article, Video, and Topic. // Content is implemented by various types like Article, Video, and Topic.
type InterfaceListOfListOfListsFieldWithPointerContent interface { type InterfaceListOfListOfListsFieldWithPointerContent interface {
implementsGraphQLInterfaceInterfaceListOfListOfListsFieldWithPointerContent() 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() { 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() { 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() { 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 { func __unmarshalInterfaceListOfListOfListsFieldWithPointerContent(v *InterfaceListOfListOfListsFieldWithPointerContent, m json.RawMessage) error {
if string(m) == "null" { if string(m) == "null" {
return nil return nil
@@ -59,130 +59,75 @@ func (v *InterfaceNestingRootTopic) UnmarshalJSON(b []byte) error {
type InterfaceNestingRootTopicChildrenArticle struct { type InterfaceNestingRootTopicChildrenArticle struct {
Typename string `json:"__typename"` Typename string `json:"__typename"`
// ID is the identifier of the content. // ID is the identifier of the content.
Id testutil.ID `json:"id"` Id testutil.ID `json:"id"`
Parent InterfaceNestingRootTopicChildrenArticleParentTopic `json:"parent"` Parent InterfaceNestingRootTopicChildrenParentTopic `json:"parent"`
} }
// InterfaceNestingRootTopicChildrenArticleParentTopic includes the requested fields of the GraphQL type Topic. // InterfaceNestingRootTopicChildrenContent includes the requested fields of the GraphQL interface Content.
type InterfaceNestingRootTopicChildrenArticleParentTopic struct { //
// ID is documented in the Content interface. // InterfaceNestingRootTopicChildrenContent is implemented by the following types:
Id testutil.ID `json:"id"` // InterfaceNestingRootTopicChildrenArticle
Children []InterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent `json:"-"` // InterfaceNestingRootTopicChildrenVideo
} // InterfaceNestingRootTopicChildrenTopic
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.
// The GraphQL type's documentation follows.
// //
// Content is implemented by various types like Article, Video, and Topic.
type InterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent interface {
implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent()
}
func (v *InterfaceNestingRootTopicChildrenArticleParentTopicChildrenArticle) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent() {
}
func (v *InterfaceNestingRootTopicChildrenArticleParentTopicChildrenVideo) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent() {
}
func (v *InterfaceNestingRootTopicChildrenArticleParentTopicChildrenTopic) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent() {
}
func __unmarshalInterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent(v *InterfaceNestingRootTopicChildrenArticleParentTopicChildrenContent, 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(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)
}
}
// 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"`
}
// 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"`
}
// InterfaceNestingRootTopicChildrenContent includes the requested fields of the GraphQL type Content.
// The GraphQL type's documentation follows. // The GraphQL type's documentation follows.
// //
// Content is implemented by various types like Article, Video, and Topic. // Content is implemented by various types like Article, Video, and Topic.
type InterfaceNestingRootTopicChildrenContent interface { type InterfaceNestingRootTopicChildrenContent interface {
implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenContent() 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 *InterfaceNestingRootTopicChildrenArticle) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenContent() { func (v *InterfaceNestingRootTopicChildrenArticle) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenContent() {
} }
// GetTypename is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenContent.
func (v *InterfaceNestingRootTopicChildrenArticle) GetTypename() string { return v.Typename }
// GetId is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenContent.
func (v *InterfaceNestingRootTopicChildrenArticle) GetId() testutil.ID { return v.Id }
// GetParent is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenContent.
func (v *InterfaceNestingRootTopicChildrenArticle) GetParent() InterfaceNestingRootTopicChildrenParentTopic {
return v.Parent
}
func (v *InterfaceNestingRootTopicChildrenVideo) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenContent() { func (v *InterfaceNestingRootTopicChildrenVideo) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenContent() {
} }
// GetTypename is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenContent.
func (v *InterfaceNestingRootTopicChildrenVideo) GetTypename() string { return v.Typename }
// GetId is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenContent.
func (v *InterfaceNestingRootTopicChildrenVideo) GetId() testutil.ID { return v.Id }
// GetParent is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenContent.
func (v *InterfaceNestingRootTopicChildrenVideo) GetParent() InterfaceNestingRootTopicChildrenParentTopic {
return v.Parent
}
func (v *InterfaceNestingRootTopicChildrenTopic) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenContent() { 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 { func __unmarshalInterfaceNestingRootTopicChildrenContent(v *InterfaceNestingRootTopicChildrenContent, m json.RawMessage) error {
if string(m) == "null" { if string(m) == "null" {
return nil return nil
@@ -212,30 +157,22 @@ func __unmarshalInterfaceNestingRootTopicChildrenContent(v *InterfaceNestingRoot
} }
} }
// InterfaceNestingRootTopicChildrenTopic includes the requested fields of the GraphQL type Topic. // InterfaceNestingRootTopicChildrenParentTopic includes the requested fields of the GraphQL type Topic.
type InterfaceNestingRootTopicChildrenTopic struct { type InterfaceNestingRootTopicChildrenParentTopic 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 {
// ID is documented in the Content interface. // ID is documented in the Content interface.
Id testutil.ID `json:"id"` Id testutil.ID `json:"id"`
Children []InterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent `json:"-"` 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 { var firstPass struct {
*InterfaceNestingRootTopicChildrenTopicParentTopicWrapper *InterfaceNestingRootTopicChildrenParentTopicWrapper
Children []json.RawMessage `json:"children"` Children []json.RawMessage `json:"children"`
} }
firstPass.InterfaceNestingRootTopicChildrenTopicParentTopicWrapper = (*InterfaceNestingRootTopicChildrenTopicParentTopicWrapper)(v) firstPass.InterfaceNestingRootTopicChildrenParentTopicWrapper = (*InterfaceNestingRootTopicChildrenParentTopicWrapper)(v)
err := json.Unmarshal(b, &firstPass) err := json.Unmarshal(b, &firstPass)
if err != nil { if err != nil {
@@ -246,11 +183,11 @@ func (v *InterfaceNestingRootTopicChildrenTopicParentTopic) UnmarshalJSON(b []by
target := &v.Children target := &v.Children
raw := firstPass.Children raw := firstPass.Children
*target = make( *target = make(
[]InterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent, []InterfaceNestingRootTopicChildrenParentTopicChildrenContent,
len(raw)) len(raw))
for i, raw := range raw { for i, raw := range raw {
target := &(*target)[i] target := &(*target)[i]
err = __unmarshalInterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent( err = __unmarshalInterfaceNestingRootTopicChildrenParentTopicChildrenContent(
target, raw) target, raw)
if err != nil { if err != nil {
return err return err
@@ -260,29 +197,70 @@ func (v *InterfaceNestingRootTopicChildrenTopicParentTopic) UnmarshalJSON(b []by
return nil return nil
} }
// InterfaceNestingRootTopicChildrenTopicParentTopicChildrenArticle includes the requested fields of the GraphQL type Article. // InterfaceNestingRootTopicChildrenParentTopicChildrenArticle includes the requested fields of the GraphQL type Article.
type InterfaceNestingRootTopicChildrenTopicParentTopicChildrenArticle struct { type InterfaceNestingRootTopicChildrenParentTopicChildrenArticle struct {
Typename string `json:"__typename"` Typename string `json:"__typename"`
// ID is the identifier of the content. // ID is the identifier of the content.
Id testutil.ID `json:"id"` 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. // The GraphQL type's documentation follows.
// //
// Content is implemented by various types like Article, Video, and Topic. // Content is implemented by various types like Article, Video, and Topic.
type InterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent interface { type InterfaceNestingRootTopicChildrenParentTopicChildrenContent interface {
implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent() 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 *InterfaceNestingRootTopicChildrenParentTopicChildrenArticle) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenParentTopicChildrenContent() {
}
func (v *InterfaceNestingRootTopicChildrenTopicParentTopicChildrenVideo) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent() {
}
func (v *InterfaceNestingRootTopicChildrenTopicParentTopicChildrenTopic) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent() {
} }
func __unmarshalInterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent(v *InterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent, m json.RawMessage) error { // GetTypename is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenParentTopicChildrenContent.
func (v *InterfaceNestingRootTopicChildrenParentTopicChildrenArticle) GetTypename() string {
return v.Typename
}
// GetId is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenParentTopicChildrenContent.
func (v *InterfaceNestingRootTopicChildrenParentTopicChildrenArticle) GetId() testutil.ID {
return v.Id
}
func (v *InterfaceNestingRootTopicChildrenParentTopicChildrenVideo) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenParentTopicChildrenContent() {
}
// GetTypename is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenParentTopicChildrenContent.
func (v *InterfaceNestingRootTopicChildrenParentTopicChildrenVideo) GetTypename() string {
return v.Typename
}
// GetId is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenParentTopicChildrenContent.
func (v *InterfaceNestingRootTopicChildrenParentTopicChildrenVideo) GetId() testutil.ID { return v.Id }
func (v *InterfaceNestingRootTopicChildrenParentTopicChildrenTopic) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenParentTopicChildrenContent() {
}
// GetTypename is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenParentTopicChildrenContent.
func (v *InterfaceNestingRootTopicChildrenParentTopicChildrenTopic) GetTypename() string {
return v.Typename
}
// GetId is a part of, and documented with, the interface InterfaceNestingRootTopicChildrenParentTopicChildrenContent.
func (v *InterfaceNestingRootTopicChildrenParentTopicChildrenTopic) GetId() testutil.ID { return v.Id }
func __unmarshalInterfaceNestingRootTopicChildrenParentTopicChildrenContent(v *InterfaceNestingRootTopicChildrenParentTopicChildrenContent, m json.RawMessage) error {
if string(m) == "null" { if string(m) == "null" {
return nil return nil
} }
@@ -297,145 +275,48 @@ func __unmarshalInterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent
switch tn.TypeName { switch tn.TypeName {
case "Article": case "Article":
*v = new(InterfaceNestingRootTopicChildrenTopicParentTopicChildrenArticle) *v = new(InterfaceNestingRootTopicChildrenParentTopicChildrenArticle)
return json.Unmarshal(m, *v) return json.Unmarshal(m, *v)
case "Video": case "Video":
*v = new(InterfaceNestingRootTopicChildrenTopicParentTopicChildrenVideo) *v = new(InterfaceNestingRootTopicChildrenParentTopicChildrenVideo)
return json.Unmarshal(m, *v) return json.Unmarshal(m, *v)
case "Topic": case "Topic":
*v = new(InterfaceNestingRootTopicChildrenTopicParentTopicChildrenTopic) *v = new(InterfaceNestingRootTopicChildrenParentTopicChildrenTopic)
return json.Unmarshal(m, *v) return json.Unmarshal(m, *v)
default: default:
return fmt.Errorf( return fmt.Errorf(
`Unexpected concrete type for InterfaceNestingRootTopicChildrenTopicParentTopicChildrenContent: "%v"`, tn.TypeName) `Unexpected concrete type for InterfaceNestingRootTopicChildrenParentTopicChildrenContent: "%v"`, tn.TypeName)
} }
} }
// InterfaceNestingRootTopicChildrenTopicParentTopicChildrenTopic includes the requested fields of the GraphQL type Topic. // InterfaceNestingRootTopicChildrenParentTopicChildrenTopic includes the requested fields of the GraphQL type Topic.
type InterfaceNestingRootTopicChildrenTopicParentTopicChildrenTopic struct { type InterfaceNestingRootTopicChildrenParentTopicChildrenTopic struct {
Typename string `json:"__typename"` Typename string `json:"__typename"`
// ID is the identifier of the content. // ID is the identifier of the content.
Id testutil.ID `json:"id"` Id testutil.ID `json:"id"`
} }
// InterfaceNestingRootTopicChildrenTopicParentTopicChildrenVideo includes the requested fields of the GraphQL type Video. // InterfaceNestingRootTopicChildrenParentTopicChildrenVideo includes the requested fields of the GraphQL type Video.
type InterfaceNestingRootTopicChildrenTopicParentTopicChildrenVideo struct { type InterfaceNestingRootTopicChildrenParentTopicChildrenVideo struct {
Typename string `json:"__typename"` Typename string `json:"__typename"`
// ID is the identifier of the content. // ID is the identifier of the content.
Id testutil.ID `json:"id"` 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. // InterfaceNestingRootTopicChildrenVideo includes the requested fields of the GraphQL type Video.
type InterfaceNestingRootTopicChildrenVideo struct { type InterfaceNestingRootTopicChildrenVideo struct {
Typename string `json:"__typename"` Typename string `json:"__typename"`
// ID is the identifier of the content. // ID is the identifier of the content.
Id testutil.ID `json:"id"` Id testutil.ID `json:"id"`
Parent InterfaceNestingRootTopicChildrenVideoParentTopic `json:"parent"` Parent InterfaceNestingRootTopicChildrenParentTopic `json:"parent"`
}
// 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:"-"`
}
func (v *InterfaceNestingRootTopicChildrenVideoParentTopic) UnmarshalJSON(b []byte) error {
type InterfaceNestingRootTopicChildrenVideoParentTopicWrapper InterfaceNestingRootTopicChildrenVideoParentTopic
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"`
}
// 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()
}
func (v *InterfaceNestingRootTopicChildrenVideoParentTopicChildrenArticle) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent() {
}
func (v *InterfaceNestingRootTopicChildrenVideoParentTopicChildrenVideo) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent() {
}
func (v *InterfaceNestingRootTopicChildrenVideoParentTopicChildrenTopic) implementsGraphQLInterfaceInterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent() {
}
func __unmarshalInterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent(v *InterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent, 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(InterfaceNestingRootTopicChildrenVideoParentTopicChildrenArticle)
return json.Unmarshal(m, *v)
case "Video":
*v = new(InterfaceNestingRootTopicChildrenVideoParentTopicChildrenVideo)
return json.Unmarshal(m, *v)
case "Topic":
*v = new(InterfaceNestingRootTopicChildrenVideoParentTopicChildrenTopic)
return json.Unmarshal(m, *v)
default:
return fmt.Errorf(
`Unexpected concrete type for InterfaceNestingRootTopicChildrenVideoParentTopicChildrenContent: "%v"`, tn.TypeName)
}
}
// InterfaceNestingRootTopicChildrenVideoParentTopicChildrenTopic includes the requested fields of the GraphQL type Topic.
type InterfaceNestingRootTopicChildrenVideoParentTopicChildrenTopic 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 {
Typename string `json:"__typename"`
// ID is the identifier of the content.
Id testutil.ID `json:"id"`
} }
func InterfaceNesting( func InterfaceNesting(
@@ -18,21 +18,65 @@ type InterfaceNoFragmentsQueryRandomItemArticle struct {
Name string `json:"name"` 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. // The GraphQL type's documentation follows.
// //
// Content is implemented by various types like Article, Video, and Topic. // Content is implemented by various types like Article, Video, and Topic.
type InterfaceNoFragmentsQueryRandomItemContent interface { type InterfaceNoFragmentsQueryRandomItemContent interface {
implementsGraphQLInterfaceInterfaceNoFragmentsQueryRandomItemContent() 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() { 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() { 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() { 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 { func __unmarshalInterfaceNoFragmentsQueryRandomItemContent(v *InterfaceNoFragmentsQueryRandomItemContent, m json.RawMessage) error {
if string(m) == "null" { if string(m) == "null" {
return nil return nil
@@ -86,21 +130,71 @@ type InterfaceNoFragmentsQueryRandomItemWithTypeNameArticle struct {
Name string `json:"name"` 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. // The GraphQL type's documentation follows.
// //
// Content is implemented by various types like Article, Video, and Topic. // Content is implemented by various types like Article, Video, and Topic.
type InterfaceNoFragmentsQueryRandomItemWithTypeNameContent interface { type InterfaceNoFragmentsQueryRandomItemWithTypeNameContent interface {
implementsGraphQLInterfaceInterfaceNoFragmentsQueryRandomItemWithTypeNameContent() 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() { 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() { 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() { 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 { func __unmarshalInterfaceNoFragmentsQueryRandomItemWithTypeNameContent(v *InterfaceNoFragmentsQueryRandomItemWithTypeNameContent, m json.RawMessage) error {
if string(m) == "null" { if string(m) == "null" {
return nil return nil
@@ -217,21 +311,65 @@ type InterfaceNoFragmentsQueryWithPointerArticle struct {
Name *string `json:"name"` 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. // The GraphQL type's documentation follows.
// //
// Content is implemented by various types like Article, Video, and Topic. // Content is implemented by various types like Article, Video, and Topic.
type InterfaceNoFragmentsQueryWithPointerContent interface { type InterfaceNoFragmentsQueryWithPointerContent interface {
implementsGraphQLInterfaceInterfaceNoFragmentsQueryWithPointerContent() 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() { 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() { 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() { 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 { func __unmarshalInterfaceNoFragmentsQueryWithPointerContent(v *InterfaceNoFragmentsQueryWithPointerContent, m json.RawMessage) error {
if string(m) == "null" { if string(m) == "null" {
return nil return nil
@@ -14,19 +14,33 @@ type UnionNoFragmentsQueryRandomLeafArticle struct {
Typename string `json:"__typename"` 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. // The GraphQL type's documentation follows.
// //
// LeafContent represents content items that can't have child-nodes. // LeafContent represents content items that can't have child-nodes.
type UnionNoFragmentsQueryRandomLeafLeafContent interface { type UnionNoFragmentsQueryRandomLeafLeafContent interface {
implementsGraphQLInterfaceUnionNoFragmentsQueryRandomLeafLeafContent() implementsGraphQLInterfaceUnionNoFragmentsQueryRandomLeafLeafContent()
// GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values).
GetTypename() string
} }
func (v *UnionNoFragmentsQueryRandomLeafArticle) implementsGraphQLInterfaceUnionNoFragmentsQueryRandomLeafLeafContent() { 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() { 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 { func __unmarshalUnionNoFragmentsQueryRandomLeafLeafContent(v *UnionNoFragmentsQueryRandomLeafLeafContent, m json.RawMessage) error {
if string(m) == "null" { if string(m) == "null" {
return nil return nil
+70 -24
View File
@@ -114,7 +114,8 @@ type goStructType struct {
type goStructField struct { type goStructField struct {
GoName string GoName string
GoType goType 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 Description string
} }
@@ -126,7 +127,20 @@ func isAbstract(typ goType) bool {
func (typ *goStructType) WriteDefinition(w io.Writer, g *generator) error { func (typ *goStructType) WriteDefinition(w io.Writer, g *generator) error {
description := typ.Description description := typ.Description
if typ.Incomplete { 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) writeDescription(w, description)
@@ -182,28 +196,76 @@ func (typ *goStructType) AbstractFields() []*goStructField {
// goInterfaceType represents a Go interface type, used to represent a GraphQL // goInterfaceType represents a Go interface type, used to represent a GraphQL
// interface or union type. // interface or union type.
type goInterfaceType struct { type goInterfaceType struct {
GoName string GoName string
Description string Description string
GraphQLName string GraphQLName string
// Fields shared by all the interface's implementations;
// we'll generate getter methods for each.
SharedFields []*goStructField
Implementations []*goStructType Implementations []*goStructType
} }
func (typ *goInterfaceType) WriteDefinition(w io.Writer, g *generator) error { func (typ *goInterfaceType) WriteDefinition(w io.Writer, g *generator) error {
// TODO(benkraft): also mention the list of implementations. goTypeNames := make([]string, len(typ.Implementations))
description := incompleteTypeDescription(typ.GoName, typ.GraphQLName, typ.Description) 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) writeDescription(w, description)
// Write the interface. // Write the interface.
fmt.Fprintf(w, "type %s interface {\n", typ.GoName) fmt.Fprintf(w, "type %s interface {\n", typ.GoName)
implementsMethodName := fmt.Sprintf("implementsGraphQLInterface%v", 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) 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") fmt.Fprintf(w, "}\n")
// Now, write out the implementations. // Now, write out the implementations.
for _, impl := range typ.Implementations { for _, impl := range typ.Implementations {
fmt.Fprintf(w, "func (v *%s) %s() {}\n", fmt.Fprintf(w, "func (v *%s) %s() {}\n",
impl.Reference(), implementsMethodName) 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.<name>`. 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 // Finally, write the unmarshal-helper, which will be called by struct
@@ -246,22 +308,6 @@ func (typ *goEnumType) IsPointer() bool { return false }
func (typ *goStructType) IsPointer() bool { return false } func (typ *goStructType) IsPointer() bool { return false }
func (typ *goInterfaceType) 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) { func writeDescription(w io.Writer, desc string) {
if desc != "" { if desc != "" {
for _, line := range strings.Split(desc, "\n") { for _, line := range strings.Split(desc, "\n") {
+102 -3
View File
@@ -17,16 +17,49 @@ type queryWithInterfaceListFieldBeingsAnimal struct {
Name string `json:"name"` 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 { type queryWithInterfaceListFieldBeingsBeing interface {
implementsGraphQLInterfacequeryWithInterfaceListFieldBeingsBeing() 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() { 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() { 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 { func __unmarshalqueryWithInterfaceListFieldBeingsBeing(v *queryWithInterfaceListFieldBeingsBeing, m json.RawMessage) error {
if string(m) == "null" { if string(m) == "null" {
return nil return nil
@@ -105,16 +138,49 @@ type queryWithInterfaceListPointerFieldBeingsAnimal struct {
Name string `json:"name"` Name string `json:"name"`
} }
// queryWithInterfaceListPointerFieldBeingsBeing includes the requested fields of the GraphQL type Being. // queryWithInterfaceListPointerFieldBeingsBeing includes the requested fields of the GraphQL interface Being.
//
// queryWithInterfaceListPointerFieldBeingsBeing is implemented by the following types:
// queryWithInterfaceListPointerFieldBeingsUser
// queryWithInterfaceListPointerFieldBeingsAnimal
//
// The GraphQL type's documentation follows.
//
//
type queryWithInterfaceListPointerFieldBeingsBeing interface { type queryWithInterfaceListPointerFieldBeingsBeing interface {
implementsGraphQLInterfacequeryWithInterfaceListPointerFieldBeingsBeing() implementsGraphQLInterfacequeryWithInterfaceListPointerFieldBeingsBeing()
// 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 *queryWithInterfaceListPointerFieldBeingsUser) implementsGraphQLInterfacequeryWithInterfaceListPointerFieldBeingsBeing() { func (v *queryWithInterfaceListPointerFieldBeingsUser) implementsGraphQLInterfacequeryWithInterfaceListPointerFieldBeingsBeing() {
} }
// GetTypename is a part of, and documented with, the interface queryWithInterfaceListPointerFieldBeingsBeing.
func (v *queryWithInterfaceListPointerFieldBeingsUser) GetTypename() string { return v.Typename }
// GetId is a part of, and documented with, the interface queryWithInterfaceListPointerFieldBeingsBeing.
func (v *queryWithInterfaceListPointerFieldBeingsUser) GetId() string { return v.Id }
// GetName is a part of, and documented with, the interface queryWithInterfaceListPointerFieldBeingsBeing.
func (v *queryWithInterfaceListPointerFieldBeingsUser) GetName() string { return v.Name }
func (v *queryWithInterfaceListPointerFieldBeingsAnimal) implementsGraphQLInterfacequeryWithInterfaceListPointerFieldBeingsBeing() { func (v *queryWithInterfaceListPointerFieldBeingsAnimal) implementsGraphQLInterfacequeryWithInterfaceListPointerFieldBeingsBeing() {
} }
// GetTypename is a part of, and documented with, the interface queryWithInterfaceListPointerFieldBeingsBeing.
func (v *queryWithInterfaceListPointerFieldBeingsAnimal) GetTypename() string { return v.Typename }
// GetId is a part of, and documented with, the interface queryWithInterfaceListPointerFieldBeingsBeing.
func (v *queryWithInterfaceListPointerFieldBeingsAnimal) GetId() string { return v.Id }
// GetName is a part of, and documented with, the interface queryWithInterfaceListPointerFieldBeingsBeing.
func (v *queryWithInterfaceListPointerFieldBeingsAnimal) GetName() string { return v.Name }
func __unmarshalqueryWithInterfaceListPointerFieldBeingsBeing(v *queryWithInterfaceListPointerFieldBeingsBeing, m json.RawMessage) error { func __unmarshalqueryWithInterfaceListPointerFieldBeingsBeing(v *queryWithInterfaceListPointerFieldBeingsBeing, m json.RawMessage) error {
if string(m) == "null" { if string(m) == "null" {
return nil return nil
@@ -187,16 +253,49 @@ func (v *queryWithInterfaceListPointerFieldResponse) UnmarshalJSON(b []byte) err
return nil 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 { type queryWithInterfaceNoFragmentsBeing interface {
implementsGraphQLInterfacequeryWithInterfaceNoFragmentsBeing() 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() { 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() { 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 { func __unmarshalqueryWithInterfaceNoFragmentsBeing(v *queryWithInterfaceNoFragmentsBeing, m json.RawMessage) error {
if string(m) == "null" { if string(m) == "null" {
return nil return nil
+45 -1
View File
@@ -71,9 +71,18 @@ func TestInterfaceNoFragments(t *testing.T) {
resp, err := queryWithInterfaceNoFragments(ctx, client, "1") resp, err := queryWithInterfaceNoFragments(ctx, client, "1")
require.NoError(t, err) 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, "1", resp.Me.Id)
assert.Equal(t, "Yours Truly", resp.Me.Name) 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) user, ok := resp.Being.(*queryWithInterfaceNoFragmentsBeingUser)
require.Truef(t, ok, "got %T, not User", resp.Being) require.Truef(t, ok, "got %T, not User", resp.Being)
assert.Equal(t, "1", user.Id) assert.Equal(t, "1", user.Id)
@@ -82,9 +91,17 @@ func TestInterfaceNoFragments(t *testing.T) {
resp, err = queryWithInterfaceNoFragments(ctx, client, "3") resp, err = queryWithInterfaceNoFragments(ctx, client, "3")
require.NoError(t, err) 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, "1", resp.Me.Id)
assert.Equal(t, "Yours Truly", resp.Me.Name) 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) animal, ok := resp.Being.(*queryWithInterfaceNoFragmentsBeingAnimal)
require.Truef(t, ok, "got %T, not Animal", resp.Being) require.Truef(t, ok, "got %T, not Animal", resp.Being)
assert.Equal(t, "3", animal.Id) assert.Equal(t, "3", animal.Id)
@@ -93,6 +110,10 @@ func TestInterfaceNoFragments(t *testing.T) {
resp, err = queryWithInterfaceNoFragments(ctx, client, "4757233945723") resp, err = queryWithInterfaceNoFragments(ctx, client, "4757233945723")
require.NoError(t, err) 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, "1", resp.Me.Id)
assert.Equal(t, "Yours Truly", resp.Me.Name) assert.Equal(t, "Yours Truly", resp.Me.Name)
@@ -116,11 +137,25 @@ func TestInterfaceListField(t *testing.T) {
require.Len(t, resp.Beings, 3) 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) user, ok := resp.Beings[0].(*queryWithInterfaceListFieldBeingsUser)
require.Truef(t, ok, "got %T, not User", resp.Beings[0]) require.Truef(t, ok, "got %T, not User", resp.Beings[0])
assert.Equal(t, "1", user.Id) assert.Equal(t, "1", user.Id)
assert.Equal(t, "Yours Truly", user.Name) 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) animal, ok := resp.Beings[1].(*queryWithInterfaceListFieldBeingsAnimal)
require.Truef(t, ok, "got %T, not Animal", resp.Beings[1]) require.Truef(t, ok, "got %T, not Animal", resp.Beings[1])
assert.Equal(t, "3", animal.Id) assert.Equal(t, "3", animal.Id)
@@ -149,11 +184,20 @@ func TestInterfaceListPointerField(t *testing.T) {
require.Len(t, resp.Beings, 3) require.Len(t, resp.Beings, 3)
// 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]).(*queryWithInterfaceListPointerFieldBeingsUser) user, ok := (*resp.Beings[0]).(*queryWithInterfaceListPointerFieldBeingsUser)
require.Truef(t, ok, "got %T, not User", resp.Beings[0]) require.Truef(t, ok, "got %T, not User", (*resp.Beings[0]))
assert.Equal(t, "1", user.Id) assert.Equal(t, "1", user.Id)
assert.Equal(t, "Yours Truly", user.Name) 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]).(*queryWithInterfaceListPointerFieldBeingsAnimal) animal, ok := (*resp.Beings[1]).(*queryWithInterfaceListPointerFieldBeingsAnimal)
require.Truef(t, ok, "got %T, not Animal", resp.Beings[1]) require.Truef(t, ok, "got %T, not Animal", resp.Beings[1])
assert.Equal(t, "3", animal.Id) assert.Equal(t, "3", animal.Id)