From 0e48e3c5667b522ef0b44020dab4cd5b477061c2 Mon Sep 17 00:00:00 2001 From: Ben Kraft Date: Thu, 2 Jun 2022 12:43:34 -0700 Subject: [PATCH] Add tests to check that genqlient handles covariance I didn't realize until today that implementations of GraphQL interfaces are actually allowed to be covariant: if the interface has a field `f: T`, then the implementations may have fields `f: U` where `U` is a subtype of `T` (for example `U` may be an implementation of the interface `T`, or `U` may be `T!` if `T` is non-nullable. (I thought it had to be `f: T` exactly.) So I figured I'd add a test and see what breaks. Surprisingly, and despite the fact that Go interfaces do *not* allow covariance, everything... worked? There's at least one place where it's possible we could ideally use a more specific type [1], but for now I just wanted to make sure we at least write something that builds and is vaguely reasonable. Of course I'm not sure if there's anything I've missed (some day I need to find a fuzzing engine that can fuzz GraphQL). [1] Specifically, the field `CovariantInterfaceImplementationRandomItemTopic.Next` might ideally have type `...NextContentTopic`, not `...NextContent`; we know it's a topic. This doesn't directly cause covariance problems in Go: the method `GetNext` still returns `...NextContent` so the interface matches. But that trick doesn't work for the sibling field `.Related` which is slice-typed: or rather, we'd need the method to copy the slice to the correct type. (Not to mention the implemention of any change here would require a bunch of plumbing because the AST doesn't quite have what we want.) So it's probably best to just keep this as-is for simplicity and consistency. Test plan: make check --- .../CovariantInterfaceImplementation.graphql | 23 + generate/testdata/queries/schema.graphql | 8 + ...ovariantInterfaceImplementation.graphql.go | 2412 +++++++++++++++++ ...ariantInterfaceImplementation.graphql.json | 9 + 4 files changed, 2452 insertions(+) create mode 100644 generate/testdata/queries/CovariantInterfaceImplementation.graphql create mode 100644 generate/testdata/snapshots/TestGenerate-CovariantInterfaceImplementation.graphql-CovariantInterfaceImplementation.graphql.go create mode 100644 generate/testdata/snapshots/TestGenerate-CovariantInterfaceImplementation.graphql-CovariantInterfaceImplementation.graphql.json diff --git a/generate/testdata/queries/CovariantInterfaceImplementation.graphql b/generate/testdata/queries/CovariantInterfaceImplementation.graphql new file mode 100644 index 00000000..884877ff --- /dev/null +++ b/generate/testdata/queries/CovariantInterfaceImplementation.graphql @@ -0,0 +1,23 @@ +query CovariantInterfaceImplementation { + randomItem { + id + next { ...ContentFields } + related { ...ContentFields } + } + root { + ...ContentFields + ...TopicFields + next { ...TopicFields } + related { ...TopicFields } + } +} + +fragment ContentFields on Content { + next { id } + related { id } +} + +fragment TopicFields on Topic { + next { id } + related { id } +} diff --git a/generate/testdata/queries/schema.graphql b/generate/testdata/queries/schema.graphql index 4e951bba..a83396f7 100644 --- a/generate/testdata/queries/schema.graphql +++ b/generate/testdata/queries/schema.graphql @@ -84,6 +84,8 @@ interface Content { name: String! parent: Topic url: String! + next: Content + related: [Content!] } """An object with a duration, like a video.""" @@ -102,6 +104,8 @@ type Article implements Content { url: String! text: String! thumbnail: StuffThumbnail + next: Content + related: [Content!] } type StuffThumbnail { # for articles, but let's give the name-generator a hard time. @@ -117,6 +121,8 @@ type Video implements Content & HasDuration { url: String! duration: Int! thumbnail: Thumbnail + next: Content + related: [Content!] } type Thumbnail { # for videos, but let's give the name-generator a hard time. @@ -133,6 +139,8 @@ type Topic implements Content { children: [Content!]! videoChildren: [Video!]! schoolGrade: String + next: Topic + related: [Topic!] } input RecursiveInput { diff --git a/generate/testdata/snapshots/TestGenerate-CovariantInterfaceImplementation.graphql-CovariantInterfaceImplementation.graphql.go b/generate/testdata/snapshots/TestGenerate-CovariantInterfaceImplementation.graphql-CovariantInterfaceImplementation.graphql.go new file mode 100644 index 00000000..84f10e84 --- /dev/null +++ b/generate/testdata/snapshots/TestGenerate-CovariantInterfaceImplementation.graphql-CovariantInterfaceImplementation.graphql.go @@ -0,0 +1,2412 @@ +// Code generated by github.com/Khan/genqlient, DO NOT EDIT. + +package test + +import ( + "encoding/json" + "fmt" + + "github.com/Khan/genqlient/graphql" + "github.com/Khan/genqlient/internal/testutil" +) + +// ContentFields includes the GraphQL fields of Content requested by the fragment ContentFields. +// The GraphQL type's documentation follows. +// +// Content is implemented by various types like Article, Video, and Topic. +// +// ContentFields is implemented by the following types: +// ContentFieldsArticle +// ContentFieldsVideo +// ContentFieldsTopic +type ContentFields interface { + implementsGraphQLInterfaceContentFields() + // GetNext returns the interface-field "next" from its implementation. + GetNext() ContentFieldsNextContent + // GetRelated returns the interface-field "related" from its implementation. + GetRelated() []ContentFieldsRelatedContent +} + +func (v *ContentFieldsArticle) implementsGraphQLInterfaceContentFields() {} +func (v *ContentFieldsVideo) implementsGraphQLInterfaceContentFields() {} +func (v *ContentFieldsTopic) implementsGraphQLInterfaceContentFields() {} + +func __unmarshalContentFields(b []byte, v *ContentFields) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Article": + *v = new(ContentFieldsArticle) + return json.Unmarshal(b, *v) + case "Video": + *v = new(ContentFieldsVideo) + return json.Unmarshal(b, *v) + case "Topic": + *v = new(ContentFieldsTopic) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing Content.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for ContentFields: "%v"`, tn.TypeName) + } +} + +func __marshalContentFields(v *ContentFields) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *ContentFieldsArticle: + typename = "Article" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalContentFieldsArticle + }{typename, premarshaled} + return json.Marshal(result) + case *ContentFieldsVideo: + typename = "Video" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalContentFieldsVideo + }{typename, premarshaled} + return json.Marshal(result) + case *ContentFieldsTopic: + typename = "Topic" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalContentFieldsTopic + }{typename, premarshaled} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for ContentFields: "%T"`, v) + } +} + +// ContentFields includes the GraphQL fields of Article requested by the fragment ContentFields. +// The GraphQL type's documentation follows. +// +// Content is implemented by various types like Article, Video, and Topic. +type ContentFieldsArticle struct { + Next ContentFieldsNextContent `json:"-"` + Related []ContentFieldsRelatedContent `json:"-"` +} + +// GetNext returns ContentFieldsArticle.Next, and is useful for accessing the field via an interface. +func (v *ContentFieldsArticle) GetNext() ContentFieldsNextContent { return v.Next } + +// GetRelated returns ContentFieldsArticle.Related, and is useful for accessing the field via an interface. +func (v *ContentFieldsArticle) GetRelated() []ContentFieldsRelatedContent { return v.Related } + +func (v *ContentFieldsArticle) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ContentFieldsArticle + Next json.RawMessage `json:"next"` + Related []json.RawMessage `json:"related"` + graphql.NoUnmarshalJSON + } + firstPass.ContentFieldsArticle = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Next + src := firstPass.Next + if len(src) != 0 && string(src) != "null" { + err = __unmarshalContentFieldsNextContent( + src, dst) + if err != nil { + return fmt.Errorf( + "Unable to unmarshal ContentFieldsArticle.Next: %w", err) + } + } + } + + { + dst := &v.Related + src := firstPass.Related + *dst = make( + []ContentFieldsRelatedContent, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + if len(src) != 0 && string(src) != "null" { + err = __unmarshalContentFieldsRelatedContent( + src, dst) + if err != nil { + return fmt.Errorf( + "Unable to unmarshal ContentFieldsArticle.Related: %w", err) + } + } + } + } + return nil +} + +type __premarshalContentFieldsArticle struct { + Next json.RawMessage `json:"next"` + + Related []json.RawMessage `json:"related"` +} + +func (v *ContentFieldsArticle) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ContentFieldsArticle) __premarshalJSON() (*__premarshalContentFieldsArticle, error) { + var retval __premarshalContentFieldsArticle + + { + + dst := &retval.Next + src := v.Next + var err error + *dst, err = __marshalContentFieldsNextContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal ContentFieldsArticle.Next: %w", err) + } + } + { + + dst := &retval.Related + src := v.Related + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalContentFieldsRelatedContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal ContentFieldsArticle.Related: %w", err) + } + } + } + return &retval, nil +} + +// ContentFieldsNextArticle includes the requested fields of the GraphQL type Article. +type ContentFieldsNextArticle struct { + Typename string `json:"__typename"` + // ID is the identifier of the content. + Id testutil.ID `json:"id"` +} + +// GetTypename returns ContentFieldsNextArticle.Typename, and is useful for accessing the field via an interface. +func (v *ContentFieldsNextArticle) GetTypename() string { return v.Typename } + +// GetId returns ContentFieldsNextArticle.Id, and is useful for accessing the field via an interface. +func (v *ContentFieldsNextArticle) GetId() testutil.ID { return v.Id } + +// ContentFieldsNextContent includes the requested fields of the GraphQL interface Content. +// +// ContentFieldsNextContent is implemented by the following types: +// ContentFieldsNextArticle +// ContentFieldsNextVideo +// ContentFieldsNextTopic +// The GraphQL type's documentation follows. +// +// Content is implemented by various types like Article, Video, and Topic. +type ContentFieldsNextContent interface { + implementsGraphQLInterfaceContentFieldsNextContent() + // 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 *ContentFieldsNextArticle) implementsGraphQLInterfaceContentFieldsNextContent() {} +func (v *ContentFieldsNextVideo) implementsGraphQLInterfaceContentFieldsNextContent() {} +func (v *ContentFieldsNextTopic) implementsGraphQLInterfaceContentFieldsNextContent() {} + +func __unmarshalContentFieldsNextContent(b []byte, v *ContentFieldsNextContent) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Article": + *v = new(ContentFieldsNextArticle) + return json.Unmarshal(b, *v) + case "Video": + *v = new(ContentFieldsNextVideo) + return json.Unmarshal(b, *v) + case "Topic": + *v = new(ContentFieldsNextTopic) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing Content.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for ContentFieldsNextContent: "%v"`, tn.TypeName) + } +} + +func __marshalContentFieldsNextContent(v *ContentFieldsNextContent) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *ContentFieldsNextArticle: + typename = "Article" + + result := struct { + TypeName string `json:"__typename"` + *ContentFieldsNextArticle + }{typename, v} + return json.Marshal(result) + case *ContentFieldsNextVideo: + typename = "Video" + + result := struct { + TypeName string `json:"__typename"` + *ContentFieldsNextVideo + }{typename, v} + return json.Marshal(result) + case *ContentFieldsNextTopic: + typename = "Topic" + + result := struct { + TypeName string `json:"__typename"` + *ContentFieldsNextTopic + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for ContentFieldsNextContent: "%T"`, v) + } +} + +// ContentFieldsNextTopic includes the requested fields of the GraphQL type Topic. +type ContentFieldsNextTopic struct { + Typename string `json:"__typename"` + // ID is the identifier of the content. + Id testutil.ID `json:"id"` +} + +// GetTypename returns ContentFieldsNextTopic.Typename, and is useful for accessing the field via an interface. +func (v *ContentFieldsNextTopic) GetTypename() string { return v.Typename } + +// GetId returns ContentFieldsNextTopic.Id, and is useful for accessing the field via an interface. +func (v *ContentFieldsNextTopic) GetId() testutil.ID { return v.Id } + +// ContentFieldsNextVideo includes the requested fields of the GraphQL type Video. +type ContentFieldsNextVideo struct { + Typename string `json:"__typename"` + // ID is the identifier of the content. + Id testutil.ID `json:"id"` +} + +// GetTypename returns ContentFieldsNextVideo.Typename, and is useful for accessing the field via an interface. +func (v *ContentFieldsNextVideo) GetTypename() string { return v.Typename } + +// GetId returns ContentFieldsNextVideo.Id, and is useful for accessing the field via an interface. +func (v *ContentFieldsNextVideo) GetId() testutil.ID { return v.Id } + +// ContentFieldsRelatedArticle includes the requested fields of the GraphQL type Article. +type ContentFieldsRelatedArticle struct { + Typename string `json:"__typename"` + // ID is the identifier of the content. + Id testutil.ID `json:"id"` +} + +// GetTypename returns ContentFieldsRelatedArticle.Typename, and is useful for accessing the field via an interface. +func (v *ContentFieldsRelatedArticle) GetTypename() string { return v.Typename } + +// GetId returns ContentFieldsRelatedArticle.Id, and is useful for accessing the field via an interface. +func (v *ContentFieldsRelatedArticle) GetId() testutil.ID { return v.Id } + +// ContentFieldsRelatedContent includes the requested fields of the GraphQL interface Content. +// +// ContentFieldsRelatedContent is implemented by the following types: +// ContentFieldsRelatedArticle +// ContentFieldsRelatedVideo +// ContentFieldsRelatedTopic +// The GraphQL type's documentation follows. +// +// Content is implemented by various types like Article, Video, and Topic. +type ContentFieldsRelatedContent interface { + implementsGraphQLInterfaceContentFieldsRelatedContent() + // 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 *ContentFieldsRelatedArticle) implementsGraphQLInterfaceContentFieldsRelatedContent() {} +func (v *ContentFieldsRelatedVideo) implementsGraphQLInterfaceContentFieldsRelatedContent() {} +func (v *ContentFieldsRelatedTopic) implementsGraphQLInterfaceContentFieldsRelatedContent() {} + +func __unmarshalContentFieldsRelatedContent(b []byte, v *ContentFieldsRelatedContent) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Article": + *v = new(ContentFieldsRelatedArticle) + return json.Unmarshal(b, *v) + case "Video": + *v = new(ContentFieldsRelatedVideo) + return json.Unmarshal(b, *v) + case "Topic": + *v = new(ContentFieldsRelatedTopic) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing Content.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for ContentFieldsRelatedContent: "%v"`, tn.TypeName) + } +} + +func __marshalContentFieldsRelatedContent(v *ContentFieldsRelatedContent) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *ContentFieldsRelatedArticle: + typename = "Article" + + result := struct { + TypeName string `json:"__typename"` + *ContentFieldsRelatedArticle + }{typename, v} + return json.Marshal(result) + case *ContentFieldsRelatedVideo: + typename = "Video" + + result := struct { + TypeName string `json:"__typename"` + *ContentFieldsRelatedVideo + }{typename, v} + return json.Marshal(result) + case *ContentFieldsRelatedTopic: + typename = "Topic" + + result := struct { + TypeName string `json:"__typename"` + *ContentFieldsRelatedTopic + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for ContentFieldsRelatedContent: "%T"`, v) + } +} + +// ContentFieldsRelatedTopic includes the requested fields of the GraphQL type Topic. +type ContentFieldsRelatedTopic struct { + Typename string `json:"__typename"` + // ID is the identifier of the content. + Id testutil.ID `json:"id"` +} + +// GetTypename returns ContentFieldsRelatedTopic.Typename, and is useful for accessing the field via an interface. +func (v *ContentFieldsRelatedTopic) GetTypename() string { return v.Typename } + +// GetId returns ContentFieldsRelatedTopic.Id, and is useful for accessing the field via an interface. +func (v *ContentFieldsRelatedTopic) GetId() testutil.ID { return v.Id } + +// ContentFieldsRelatedVideo includes the requested fields of the GraphQL type Video. +type ContentFieldsRelatedVideo struct { + Typename string `json:"__typename"` + // ID is the identifier of the content. + Id testutil.ID `json:"id"` +} + +// GetTypename returns ContentFieldsRelatedVideo.Typename, and is useful for accessing the field via an interface. +func (v *ContentFieldsRelatedVideo) GetTypename() string { return v.Typename } + +// GetId returns ContentFieldsRelatedVideo.Id, and is useful for accessing the field via an interface. +func (v *ContentFieldsRelatedVideo) GetId() testutil.ID { return v.Id } + +// ContentFields includes the GraphQL fields of Topic requested by the fragment ContentFields. +// The GraphQL type's documentation follows. +// +// Content is implemented by various types like Article, Video, and Topic. +type ContentFieldsTopic struct { + Next ContentFieldsNextContent `json:"-"` + Related []ContentFieldsRelatedContent `json:"-"` +} + +// GetNext returns ContentFieldsTopic.Next, and is useful for accessing the field via an interface. +func (v *ContentFieldsTopic) GetNext() ContentFieldsNextContent { return v.Next } + +// GetRelated returns ContentFieldsTopic.Related, and is useful for accessing the field via an interface. +func (v *ContentFieldsTopic) GetRelated() []ContentFieldsRelatedContent { return v.Related } + +func (v *ContentFieldsTopic) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ContentFieldsTopic + Next json.RawMessage `json:"next"` + Related []json.RawMessage `json:"related"` + graphql.NoUnmarshalJSON + } + firstPass.ContentFieldsTopic = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Next + src := firstPass.Next + if len(src) != 0 && string(src) != "null" { + err = __unmarshalContentFieldsNextContent( + src, dst) + if err != nil { + return fmt.Errorf( + "Unable to unmarshal ContentFieldsTopic.Next: %w", err) + } + } + } + + { + dst := &v.Related + src := firstPass.Related + *dst = make( + []ContentFieldsRelatedContent, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + if len(src) != 0 && string(src) != "null" { + err = __unmarshalContentFieldsRelatedContent( + src, dst) + if err != nil { + return fmt.Errorf( + "Unable to unmarshal ContentFieldsTopic.Related: %w", err) + } + } + } + } + return nil +} + +type __premarshalContentFieldsTopic struct { + Next json.RawMessage `json:"next"` + + Related []json.RawMessage `json:"related"` +} + +func (v *ContentFieldsTopic) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ContentFieldsTopic) __premarshalJSON() (*__premarshalContentFieldsTopic, error) { + var retval __premarshalContentFieldsTopic + + { + + dst := &retval.Next + src := v.Next + var err error + *dst, err = __marshalContentFieldsNextContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal ContentFieldsTopic.Next: %w", err) + } + } + { + + dst := &retval.Related + src := v.Related + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalContentFieldsRelatedContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal ContentFieldsTopic.Related: %w", err) + } + } + } + return &retval, nil +} + +// ContentFields includes the GraphQL fields of Video requested by the fragment ContentFields. +// The GraphQL type's documentation follows. +// +// Content is implemented by various types like Article, Video, and Topic. +type ContentFieldsVideo struct { + Next ContentFieldsNextContent `json:"-"` + Related []ContentFieldsRelatedContent `json:"-"` +} + +// GetNext returns ContentFieldsVideo.Next, and is useful for accessing the field via an interface. +func (v *ContentFieldsVideo) GetNext() ContentFieldsNextContent { return v.Next } + +// GetRelated returns ContentFieldsVideo.Related, and is useful for accessing the field via an interface. +func (v *ContentFieldsVideo) GetRelated() []ContentFieldsRelatedContent { return v.Related } + +func (v *ContentFieldsVideo) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *ContentFieldsVideo + Next json.RawMessage `json:"next"` + Related []json.RawMessage `json:"related"` + graphql.NoUnmarshalJSON + } + firstPass.ContentFieldsVideo = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Next + src := firstPass.Next + if len(src) != 0 && string(src) != "null" { + err = __unmarshalContentFieldsNextContent( + src, dst) + if err != nil { + return fmt.Errorf( + "Unable to unmarshal ContentFieldsVideo.Next: %w", err) + } + } + } + + { + dst := &v.Related + src := firstPass.Related + *dst = make( + []ContentFieldsRelatedContent, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + if len(src) != 0 && string(src) != "null" { + err = __unmarshalContentFieldsRelatedContent( + src, dst) + if err != nil { + return fmt.Errorf( + "Unable to unmarshal ContentFieldsVideo.Related: %w", err) + } + } + } + } + return nil +} + +type __premarshalContentFieldsVideo struct { + Next json.RawMessage `json:"next"` + + Related []json.RawMessage `json:"related"` +} + +func (v *ContentFieldsVideo) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *ContentFieldsVideo) __premarshalJSON() (*__premarshalContentFieldsVideo, error) { + var retval __premarshalContentFieldsVideo + + { + + dst := &retval.Next + src := v.Next + var err error + *dst, err = __marshalContentFieldsNextContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal ContentFieldsVideo.Next: %w", err) + } + } + { + + dst := &retval.Related + src := v.Related + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalContentFieldsRelatedContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal ContentFieldsVideo.Related: %w", err) + } + } + } + return &retval, nil +} + +// CovariantInterfaceImplementationRandomItemArticle includes the requested fields of the GraphQL type Article. +type CovariantInterfaceImplementationRandomItemArticle struct { + Typename string `json:"__typename"` + // ID is the identifier of the content. + Id testutil.ID `json:"id"` + Next CovariantInterfaceImplementationRandomItemContentNextContent `json:"-"` + Related []CovariantInterfaceImplementationRandomItemContentRelatedContent `json:"-"` +} + +// GetTypename returns CovariantInterfaceImplementationRandomItemArticle.Typename, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemArticle) GetTypename() string { return v.Typename } + +// GetId returns CovariantInterfaceImplementationRandomItemArticle.Id, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemArticle) GetId() testutil.ID { return v.Id } + +// GetNext returns CovariantInterfaceImplementationRandomItemArticle.Next, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemArticle) GetNext() CovariantInterfaceImplementationRandomItemContentNextContent { + return v.Next +} + +// GetRelated returns CovariantInterfaceImplementationRandomItemArticle.Related, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemArticle) GetRelated() []CovariantInterfaceImplementationRandomItemContentRelatedContent { + return v.Related +} + +func (v *CovariantInterfaceImplementationRandomItemArticle) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CovariantInterfaceImplementationRandomItemArticle + Next json.RawMessage `json:"next"` + Related []json.RawMessage `json:"related"` + graphql.NoUnmarshalJSON + } + firstPass.CovariantInterfaceImplementationRandomItemArticle = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Next + src := firstPass.Next + if len(src) != 0 && string(src) != "null" { + err = __unmarshalCovariantInterfaceImplementationRandomItemContentNextContent( + src, dst) + if err != nil { + return fmt.Errorf( + "Unable to unmarshal CovariantInterfaceImplementationRandomItemArticle.Next: %w", err) + } + } + } + + { + dst := &v.Related + src := firstPass.Related + *dst = make( + []CovariantInterfaceImplementationRandomItemContentRelatedContent, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + if len(src) != 0 && string(src) != "null" { + err = __unmarshalCovariantInterfaceImplementationRandomItemContentRelatedContent( + src, dst) + if err != nil { + return fmt.Errorf( + "Unable to unmarshal CovariantInterfaceImplementationRandomItemArticle.Related: %w", err) + } + } + } + } + return nil +} + +type __premarshalCovariantInterfaceImplementationRandomItemArticle struct { + Typename string `json:"__typename"` + + Id testutil.ID `json:"id"` + + Next json.RawMessage `json:"next"` + + Related []json.RawMessage `json:"related"` +} + +func (v *CovariantInterfaceImplementationRandomItemArticle) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CovariantInterfaceImplementationRandomItemArticle) __premarshalJSON() (*__premarshalCovariantInterfaceImplementationRandomItemArticle, error) { + var retval __premarshalCovariantInterfaceImplementationRandomItemArticle + + retval.Typename = v.Typename + retval.Id = v.Id + { + + dst := &retval.Next + src := v.Next + var err error + *dst, err = __marshalCovariantInterfaceImplementationRandomItemContentNextContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemArticle.Next: %w", err) + } + } + { + + dst := &retval.Related + src := v.Related + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalCovariantInterfaceImplementationRandomItemContentRelatedContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemArticle.Related: %w", err) + } + } + } + return &retval, nil +} + +// CovariantInterfaceImplementationRandomItemContent includes the requested fields of the GraphQL interface Content. +// +// CovariantInterfaceImplementationRandomItemContent is implemented by the following types: +// CovariantInterfaceImplementationRandomItemArticle +// CovariantInterfaceImplementationRandomItemVideo +// CovariantInterfaceImplementationRandomItemTopic +// The GraphQL type's documentation follows. +// +// Content is implemented by various types like Article, Video, and Topic. +type CovariantInterfaceImplementationRandomItemContent interface { + implementsGraphQLInterfaceCovariantInterfaceImplementationRandomItemContent() + // 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 + // GetNext returns the interface-field "next" from its implementation. + GetNext() CovariantInterfaceImplementationRandomItemContentNextContent + // GetRelated returns the interface-field "related" from its implementation. + GetRelated() []CovariantInterfaceImplementationRandomItemContentRelatedContent +} + +func (v *CovariantInterfaceImplementationRandomItemArticle) implementsGraphQLInterfaceCovariantInterfaceImplementationRandomItemContent() { +} +func (v *CovariantInterfaceImplementationRandomItemVideo) implementsGraphQLInterfaceCovariantInterfaceImplementationRandomItemContent() { +} +func (v *CovariantInterfaceImplementationRandomItemTopic) implementsGraphQLInterfaceCovariantInterfaceImplementationRandomItemContent() { +} + +func __unmarshalCovariantInterfaceImplementationRandomItemContent(b []byte, v *CovariantInterfaceImplementationRandomItemContent) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Article": + *v = new(CovariantInterfaceImplementationRandomItemArticle) + return json.Unmarshal(b, *v) + case "Video": + *v = new(CovariantInterfaceImplementationRandomItemVideo) + return json.Unmarshal(b, *v) + case "Topic": + *v = new(CovariantInterfaceImplementationRandomItemTopic) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing Content.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for CovariantInterfaceImplementationRandomItemContent: "%v"`, tn.TypeName) + } +} + +func __marshalCovariantInterfaceImplementationRandomItemContent(v *CovariantInterfaceImplementationRandomItemContent) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *CovariantInterfaceImplementationRandomItemArticle: + typename = "Article" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalCovariantInterfaceImplementationRandomItemArticle + }{typename, premarshaled} + return json.Marshal(result) + case *CovariantInterfaceImplementationRandomItemVideo: + typename = "Video" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalCovariantInterfaceImplementationRandomItemVideo + }{typename, premarshaled} + return json.Marshal(result) + case *CovariantInterfaceImplementationRandomItemTopic: + typename = "Topic" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalCovariantInterfaceImplementationRandomItemTopic + }{typename, premarshaled} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for CovariantInterfaceImplementationRandomItemContent: "%T"`, v) + } +} + +// CovariantInterfaceImplementationRandomItemContentNextArticle includes the requested fields of the GraphQL type Article. +type CovariantInterfaceImplementationRandomItemContentNextArticle struct { + Typename string `json:"__typename"` + ContentFieldsArticle `json:"-"` +} + +// GetTypename returns CovariantInterfaceImplementationRandomItemContentNextArticle.Typename, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentNextArticle) GetTypename() string { + return v.Typename +} + +// GetNext returns CovariantInterfaceImplementationRandomItemContentNextArticle.Next, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentNextArticle) GetNext() ContentFieldsNextContent { + return v.ContentFieldsArticle.Next +} + +// GetRelated returns CovariantInterfaceImplementationRandomItemContentNextArticle.Related, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentNextArticle) GetRelated() []ContentFieldsRelatedContent { + return v.ContentFieldsArticle.Related +} + +func (v *CovariantInterfaceImplementationRandomItemContentNextArticle) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CovariantInterfaceImplementationRandomItemContentNextArticle + graphql.NoUnmarshalJSON + } + firstPass.CovariantInterfaceImplementationRandomItemContentNextArticle = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ContentFieldsArticle) + if err != nil { + return err + } + return nil +} + +type __premarshalCovariantInterfaceImplementationRandomItemContentNextArticle struct { + Typename string `json:"__typename"` + + Next json.RawMessage `json:"next"` + + Related []json.RawMessage `json:"related"` +} + +func (v *CovariantInterfaceImplementationRandomItemContentNextArticle) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CovariantInterfaceImplementationRandomItemContentNextArticle) __premarshalJSON() (*__premarshalCovariantInterfaceImplementationRandomItemContentNextArticle, error) { + var retval __premarshalCovariantInterfaceImplementationRandomItemContentNextArticle + + retval.Typename = v.Typename + { + + dst := &retval.Next + src := v.ContentFieldsArticle.Next + var err error + *dst, err = __marshalContentFieldsNextContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemContentNextArticle.ContentFieldsArticle.Next: %w", err) + } + } + { + + dst := &retval.Related + src := v.ContentFieldsArticle.Related + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalContentFieldsRelatedContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemContentNextArticle.ContentFieldsArticle.Related: %w", err) + } + } + } + return &retval, nil +} + +// CovariantInterfaceImplementationRandomItemContentNextContent includes the requested fields of the GraphQL interface Content. +// +// CovariantInterfaceImplementationRandomItemContentNextContent is implemented by the following types: +// CovariantInterfaceImplementationRandomItemContentNextArticle +// CovariantInterfaceImplementationRandomItemContentNextVideo +// CovariantInterfaceImplementationRandomItemContentNextTopic +// The GraphQL type's documentation follows. +// +// Content is implemented by various types like Article, Video, and Topic. +type CovariantInterfaceImplementationRandomItemContentNextContent interface { + implementsGraphQLInterfaceCovariantInterfaceImplementationRandomItemContentNextContent() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string + ContentFields +} + +func (v *CovariantInterfaceImplementationRandomItemContentNextArticle) implementsGraphQLInterfaceCovariantInterfaceImplementationRandomItemContentNextContent() { +} +func (v *CovariantInterfaceImplementationRandomItemContentNextVideo) implementsGraphQLInterfaceCovariantInterfaceImplementationRandomItemContentNextContent() { +} +func (v *CovariantInterfaceImplementationRandomItemContentNextTopic) implementsGraphQLInterfaceCovariantInterfaceImplementationRandomItemContentNextContent() { +} + +func __unmarshalCovariantInterfaceImplementationRandomItemContentNextContent(b []byte, v *CovariantInterfaceImplementationRandomItemContentNextContent) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Article": + *v = new(CovariantInterfaceImplementationRandomItemContentNextArticle) + return json.Unmarshal(b, *v) + case "Video": + *v = new(CovariantInterfaceImplementationRandomItemContentNextVideo) + return json.Unmarshal(b, *v) + case "Topic": + *v = new(CovariantInterfaceImplementationRandomItemContentNextTopic) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing Content.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for CovariantInterfaceImplementationRandomItemContentNextContent: "%v"`, tn.TypeName) + } +} + +func __marshalCovariantInterfaceImplementationRandomItemContentNextContent(v *CovariantInterfaceImplementationRandomItemContentNextContent) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *CovariantInterfaceImplementationRandomItemContentNextArticle: + typename = "Article" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalCovariantInterfaceImplementationRandomItemContentNextArticle + }{typename, premarshaled} + return json.Marshal(result) + case *CovariantInterfaceImplementationRandomItemContentNextVideo: + typename = "Video" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalCovariantInterfaceImplementationRandomItemContentNextVideo + }{typename, premarshaled} + return json.Marshal(result) + case *CovariantInterfaceImplementationRandomItemContentNextTopic: + typename = "Topic" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalCovariantInterfaceImplementationRandomItemContentNextTopic + }{typename, premarshaled} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for CovariantInterfaceImplementationRandomItemContentNextContent: "%T"`, v) + } +} + +// CovariantInterfaceImplementationRandomItemContentNextTopic includes the requested fields of the GraphQL type Topic. +type CovariantInterfaceImplementationRandomItemContentNextTopic struct { + Typename string `json:"__typename"` + ContentFieldsTopic `json:"-"` +} + +// GetTypename returns CovariantInterfaceImplementationRandomItemContentNextTopic.Typename, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentNextTopic) GetTypename() string { + return v.Typename +} + +// GetNext returns CovariantInterfaceImplementationRandomItemContentNextTopic.Next, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentNextTopic) GetNext() ContentFieldsNextContent { + return v.ContentFieldsTopic.Next +} + +// GetRelated returns CovariantInterfaceImplementationRandomItemContentNextTopic.Related, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentNextTopic) GetRelated() []ContentFieldsRelatedContent { + return v.ContentFieldsTopic.Related +} + +func (v *CovariantInterfaceImplementationRandomItemContentNextTopic) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CovariantInterfaceImplementationRandomItemContentNextTopic + graphql.NoUnmarshalJSON + } + firstPass.CovariantInterfaceImplementationRandomItemContentNextTopic = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ContentFieldsTopic) + if err != nil { + return err + } + return nil +} + +type __premarshalCovariantInterfaceImplementationRandomItemContentNextTopic struct { + Typename string `json:"__typename"` + + Next json.RawMessage `json:"next"` + + Related []json.RawMessage `json:"related"` +} + +func (v *CovariantInterfaceImplementationRandomItemContentNextTopic) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CovariantInterfaceImplementationRandomItemContentNextTopic) __premarshalJSON() (*__premarshalCovariantInterfaceImplementationRandomItemContentNextTopic, error) { + var retval __premarshalCovariantInterfaceImplementationRandomItemContentNextTopic + + retval.Typename = v.Typename + { + + dst := &retval.Next + src := v.ContentFieldsTopic.Next + var err error + *dst, err = __marshalContentFieldsNextContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemContentNextTopic.ContentFieldsTopic.Next: %w", err) + } + } + { + + dst := &retval.Related + src := v.ContentFieldsTopic.Related + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalContentFieldsRelatedContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemContentNextTopic.ContentFieldsTopic.Related: %w", err) + } + } + } + return &retval, nil +} + +// CovariantInterfaceImplementationRandomItemContentNextVideo includes the requested fields of the GraphQL type Video. +type CovariantInterfaceImplementationRandomItemContentNextVideo struct { + Typename string `json:"__typename"` + ContentFieldsVideo `json:"-"` +} + +// GetTypename returns CovariantInterfaceImplementationRandomItemContentNextVideo.Typename, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentNextVideo) GetTypename() string { + return v.Typename +} + +// GetNext returns CovariantInterfaceImplementationRandomItemContentNextVideo.Next, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentNextVideo) GetNext() ContentFieldsNextContent { + return v.ContentFieldsVideo.Next +} + +// GetRelated returns CovariantInterfaceImplementationRandomItemContentNextVideo.Related, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentNextVideo) GetRelated() []ContentFieldsRelatedContent { + return v.ContentFieldsVideo.Related +} + +func (v *CovariantInterfaceImplementationRandomItemContentNextVideo) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CovariantInterfaceImplementationRandomItemContentNextVideo + graphql.NoUnmarshalJSON + } + firstPass.CovariantInterfaceImplementationRandomItemContentNextVideo = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ContentFieldsVideo) + if err != nil { + return err + } + return nil +} + +type __premarshalCovariantInterfaceImplementationRandomItemContentNextVideo struct { + Typename string `json:"__typename"` + + Next json.RawMessage `json:"next"` + + Related []json.RawMessage `json:"related"` +} + +func (v *CovariantInterfaceImplementationRandomItemContentNextVideo) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CovariantInterfaceImplementationRandomItemContentNextVideo) __premarshalJSON() (*__premarshalCovariantInterfaceImplementationRandomItemContentNextVideo, error) { + var retval __premarshalCovariantInterfaceImplementationRandomItemContentNextVideo + + retval.Typename = v.Typename + { + + dst := &retval.Next + src := v.ContentFieldsVideo.Next + var err error + *dst, err = __marshalContentFieldsNextContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemContentNextVideo.ContentFieldsVideo.Next: %w", err) + } + } + { + + dst := &retval.Related + src := v.ContentFieldsVideo.Related + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalContentFieldsRelatedContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemContentNextVideo.ContentFieldsVideo.Related: %w", err) + } + } + } + return &retval, nil +} + +// CovariantInterfaceImplementationRandomItemContentRelatedArticle includes the requested fields of the GraphQL type Article. +type CovariantInterfaceImplementationRandomItemContentRelatedArticle struct { + Typename string `json:"__typename"` + ContentFieldsArticle `json:"-"` +} + +// GetTypename returns CovariantInterfaceImplementationRandomItemContentRelatedArticle.Typename, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentRelatedArticle) GetTypename() string { + return v.Typename +} + +// GetNext returns CovariantInterfaceImplementationRandomItemContentRelatedArticle.Next, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentRelatedArticle) GetNext() ContentFieldsNextContent { + return v.ContentFieldsArticle.Next +} + +// GetRelated returns CovariantInterfaceImplementationRandomItemContentRelatedArticle.Related, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentRelatedArticle) GetRelated() []ContentFieldsRelatedContent { + return v.ContentFieldsArticle.Related +} + +func (v *CovariantInterfaceImplementationRandomItemContentRelatedArticle) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CovariantInterfaceImplementationRandomItemContentRelatedArticle + graphql.NoUnmarshalJSON + } + firstPass.CovariantInterfaceImplementationRandomItemContentRelatedArticle = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ContentFieldsArticle) + if err != nil { + return err + } + return nil +} + +type __premarshalCovariantInterfaceImplementationRandomItemContentRelatedArticle struct { + Typename string `json:"__typename"` + + Next json.RawMessage `json:"next"` + + Related []json.RawMessage `json:"related"` +} + +func (v *CovariantInterfaceImplementationRandomItemContentRelatedArticle) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CovariantInterfaceImplementationRandomItemContentRelatedArticle) __premarshalJSON() (*__premarshalCovariantInterfaceImplementationRandomItemContentRelatedArticle, error) { + var retval __premarshalCovariantInterfaceImplementationRandomItemContentRelatedArticle + + retval.Typename = v.Typename + { + + dst := &retval.Next + src := v.ContentFieldsArticle.Next + var err error + *dst, err = __marshalContentFieldsNextContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemContentRelatedArticle.ContentFieldsArticle.Next: %w", err) + } + } + { + + dst := &retval.Related + src := v.ContentFieldsArticle.Related + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalContentFieldsRelatedContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemContentRelatedArticle.ContentFieldsArticle.Related: %w", err) + } + } + } + return &retval, nil +} + +// CovariantInterfaceImplementationRandomItemContentRelatedContent includes the requested fields of the GraphQL interface Content. +// +// CovariantInterfaceImplementationRandomItemContentRelatedContent is implemented by the following types: +// CovariantInterfaceImplementationRandomItemContentRelatedArticle +// CovariantInterfaceImplementationRandomItemContentRelatedVideo +// CovariantInterfaceImplementationRandomItemContentRelatedTopic +// The GraphQL type's documentation follows. +// +// Content is implemented by various types like Article, Video, and Topic. +type CovariantInterfaceImplementationRandomItemContentRelatedContent interface { + implementsGraphQLInterfaceCovariantInterfaceImplementationRandomItemContentRelatedContent() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string + ContentFields +} + +func (v *CovariantInterfaceImplementationRandomItemContentRelatedArticle) implementsGraphQLInterfaceCovariantInterfaceImplementationRandomItemContentRelatedContent() { +} +func (v *CovariantInterfaceImplementationRandomItemContentRelatedVideo) implementsGraphQLInterfaceCovariantInterfaceImplementationRandomItemContentRelatedContent() { +} +func (v *CovariantInterfaceImplementationRandomItemContentRelatedTopic) implementsGraphQLInterfaceCovariantInterfaceImplementationRandomItemContentRelatedContent() { +} + +func __unmarshalCovariantInterfaceImplementationRandomItemContentRelatedContent(b []byte, v *CovariantInterfaceImplementationRandomItemContentRelatedContent) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Article": + *v = new(CovariantInterfaceImplementationRandomItemContentRelatedArticle) + return json.Unmarshal(b, *v) + case "Video": + *v = new(CovariantInterfaceImplementationRandomItemContentRelatedVideo) + return json.Unmarshal(b, *v) + case "Topic": + *v = new(CovariantInterfaceImplementationRandomItemContentRelatedTopic) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing Content.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for CovariantInterfaceImplementationRandomItemContentRelatedContent: "%v"`, tn.TypeName) + } +} + +func __marshalCovariantInterfaceImplementationRandomItemContentRelatedContent(v *CovariantInterfaceImplementationRandomItemContentRelatedContent) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *CovariantInterfaceImplementationRandomItemContentRelatedArticle: + typename = "Article" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalCovariantInterfaceImplementationRandomItemContentRelatedArticle + }{typename, premarshaled} + return json.Marshal(result) + case *CovariantInterfaceImplementationRandomItemContentRelatedVideo: + typename = "Video" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalCovariantInterfaceImplementationRandomItemContentRelatedVideo + }{typename, premarshaled} + return json.Marshal(result) + case *CovariantInterfaceImplementationRandomItemContentRelatedTopic: + typename = "Topic" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalCovariantInterfaceImplementationRandomItemContentRelatedTopic + }{typename, premarshaled} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for CovariantInterfaceImplementationRandomItemContentRelatedContent: "%T"`, v) + } +} + +// CovariantInterfaceImplementationRandomItemContentRelatedTopic includes the requested fields of the GraphQL type Topic. +type CovariantInterfaceImplementationRandomItemContentRelatedTopic struct { + Typename string `json:"__typename"` + ContentFieldsTopic `json:"-"` +} + +// GetTypename returns CovariantInterfaceImplementationRandomItemContentRelatedTopic.Typename, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentRelatedTopic) GetTypename() string { + return v.Typename +} + +// GetNext returns CovariantInterfaceImplementationRandomItemContentRelatedTopic.Next, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentRelatedTopic) GetNext() ContentFieldsNextContent { + return v.ContentFieldsTopic.Next +} + +// GetRelated returns CovariantInterfaceImplementationRandomItemContentRelatedTopic.Related, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentRelatedTopic) GetRelated() []ContentFieldsRelatedContent { + return v.ContentFieldsTopic.Related +} + +func (v *CovariantInterfaceImplementationRandomItemContentRelatedTopic) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CovariantInterfaceImplementationRandomItemContentRelatedTopic + graphql.NoUnmarshalJSON + } + firstPass.CovariantInterfaceImplementationRandomItemContentRelatedTopic = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ContentFieldsTopic) + if err != nil { + return err + } + return nil +} + +type __premarshalCovariantInterfaceImplementationRandomItemContentRelatedTopic struct { + Typename string `json:"__typename"` + + Next json.RawMessage `json:"next"` + + Related []json.RawMessage `json:"related"` +} + +func (v *CovariantInterfaceImplementationRandomItemContentRelatedTopic) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CovariantInterfaceImplementationRandomItemContentRelatedTopic) __premarshalJSON() (*__premarshalCovariantInterfaceImplementationRandomItemContentRelatedTopic, error) { + var retval __premarshalCovariantInterfaceImplementationRandomItemContentRelatedTopic + + retval.Typename = v.Typename + { + + dst := &retval.Next + src := v.ContentFieldsTopic.Next + var err error + *dst, err = __marshalContentFieldsNextContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemContentRelatedTopic.ContentFieldsTopic.Next: %w", err) + } + } + { + + dst := &retval.Related + src := v.ContentFieldsTopic.Related + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalContentFieldsRelatedContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemContentRelatedTopic.ContentFieldsTopic.Related: %w", err) + } + } + } + return &retval, nil +} + +// CovariantInterfaceImplementationRandomItemContentRelatedVideo includes the requested fields of the GraphQL type Video. +type CovariantInterfaceImplementationRandomItemContentRelatedVideo struct { + Typename string `json:"__typename"` + ContentFieldsVideo `json:"-"` +} + +// GetTypename returns CovariantInterfaceImplementationRandomItemContentRelatedVideo.Typename, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentRelatedVideo) GetTypename() string { + return v.Typename +} + +// GetNext returns CovariantInterfaceImplementationRandomItemContentRelatedVideo.Next, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentRelatedVideo) GetNext() ContentFieldsNextContent { + return v.ContentFieldsVideo.Next +} + +// GetRelated returns CovariantInterfaceImplementationRandomItemContentRelatedVideo.Related, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemContentRelatedVideo) GetRelated() []ContentFieldsRelatedContent { + return v.ContentFieldsVideo.Related +} + +func (v *CovariantInterfaceImplementationRandomItemContentRelatedVideo) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CovariantInterfaceImplementationRandomItemContentRelatedVideo + graphql.NoUnmarshalJSON + } + firstPass.CovariantInterfaceImplementationRandomItemContentRelatedVideo = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ContentFieldsVideo) + if err != nil { + return err + } + return nil +} + +type __premarshalCovariantInterfaceImplementationRandomItemContentRelatedVideo struct { + Typename string `json:"__typename"` + + Next json.RawMessage `json:"next"` + + Related []json.RawMessage `json:"related"` +} + +func (v *CovariantInterfaceImplementationRandomItemContentRelatedVideo) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CovariantInterfaceImplementationRandomItemContentRelatedVideo) __premarshalJSON() (*__premarshalCovariantInterfaceImplementationRandomItemContentRelatedVideo, error) { + var retval __premarshalCovariantInterfaceImplementationRandomItemContentRelatedVideo + + retval.Typename = v.Typename + { + + dst := &retval.Next + src := v.ContentFieldsVideo.Next + var err error + *dst, err = __marshalContentFieldsNextContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemContentRelatedVideo.ContentFieldsVideo.Next: %w", err) + } + } + { + + dst := &retval.Related + src := v.ContentFieldsVideo.Related + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalContentFieldsRelatedContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemContentRelatedVideo.ContentFieldsVideo.Related: %w", err) + } + } + } + return &retval, nil +} + +// CovariantInterfaceImplementationRandomItemTopic includes the requested fields of the GraphQL type Topic. +type CovariantInterfaceImplementationRandomItemTopic struct { + Typename string `json:"__typename"` + // ID is the identifier of the content. + Id testutil.ID `json:"id"` + Next CovariantInterfaceImplementationRandomItemContentNextContent `json:"-"` + Related []CovariantInterfaceImplementationRandomItemContentRelatedContent `json:"-"` +} + +// GetTypename returns CovariantInterfaceImplementationRandomItemTopic.Typename, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemTopic) GetTypename() string { return v.Typename } + +// GetId returns CovariantInterfaceImplementationRandomItemTopic.Id, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemTopic) GetId() testutil.ID { return v.Id } + +// GetNext returns CovariantInterfaceImplementationRandomItemTopic.Next, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemTopic) GetNext() CovariantInterfaceImplementationRandomItemContentNextContent { + return v.Next +} + +// GetRelated returns CovariantInterfaceImplementationRandomItemTopic.Related, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemTopic) GetRelated() []CovariantInterfaceImplementationRandomItemContentRelatedContent { + return v.Related +} + +func (v *CovariantInterfaceImplementationRandomItemTopic) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CovariantInterfaceImplementationRandomItemTopic + Next json.RawMessage `json:"next"` + Related []json.RawMessage `json:"related"` + graphql.NoUnmarshalJSON + } + firstPass.CovariantInterfaceImplementationRandomItemTopic = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Next + src := firstPass.Next + if len(src) != 0 && string(src) != "null" { + err = __unmarshalCovariantInterfaceImplementationRandomItemContentNextContent( + src, dst) + if err != nil { + return fmt.Errorf( + "Unable to unmarshal CovariantInterfaceImplementationRandomItemTopic.Next: %w", err) + } + } + } + + { + dst := &v.Related + src := firstPass.Related + *dst = make( + []CovariantInterfaceImplementationRandomItemContentRelatedContent, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + if len(src) != 0 && string(src) != "null" { + err = __unmarshalCovariantInterfaceImplementationRandomItemContentRelatedContent( + src, dst) + if err != nil { + return fmt.Errorf( + "Unable to unmarshal CovariantInterfaceImplementationRandomItemTopic.Related: %w", err) + } + } + } + } + return nil +} + +type __premarshalCovariantInterfaceImplementationRandomItemTopic struct { + Typename string `json:"__typename"` + + Id testutil.ID `json:"id"` + + Next json.RawMessage `json:"next"` + + Related []json.RawMessage `json:"related"` +} + +func (v *CovariantInterfaceImplementationRandomItemTopic) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CovariantInterfaceImplementationRandomItemTopic) __premarshalJSON() (*__premarshalCovariantInterfaceImplementationRandomItemTopic, error) { + var retval __premarshalCovariantInterfaceImplementationRandomItemTopic + + retval.Typename = v.Typename + retval.Id = v.Id + { + + dst := &retval.Next + src := v.Next + var err error + *dst, err = __marshalCovariantInterfaceImplementationRandomItemContentNextContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemTopic.Next: %w", err) + } + } + { + + dst := &retval.Related + src := v.Related + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalCovariantInterfaceImplementationRandomItemContentRelatedContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemTopic.Related: %w", err) + } + } + } + return &retval, nil +} + +// CovariantInterfaceImplementationRandomItemVideo includes the requested fields of the GraphQL type Video. +type CovariantInterfaceImplementationRandomItemVideo struct { + Typename string `json:"__typename"` + // ID is the identifier of the content. + Id testutil.ID `json:"id"` + Next CovariantInterfaceImplementationRandomItemContentNextContent `json:"-"` + Related []CovariantInterfaceImplementationRandomItemContentRelatedContent `json:"-"` +} + +// GetTypename returns CovariantInterfaceImplementationRandomItemVideo.Typename, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemVideo) GetTypename() string { return v.Typename } + +// GetId returns CovariantInterfaceImplementationRandomItemVideo.Id, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemVideo) GetId() testutil.ID { return v.Id } + +// GetNext returns CovariantInterfaceImplementationRandomItemVideo.Next, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemVideo) GetNext() CovariantInterfaceImplementationRandomItemContentNextContent { + return v.Next +} + +// GetRelated returns CovariantInterfaceImplementationRandomItemVideo.Related, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRandomItemVideo) GetRelated() []CovariantInterfaceImplementationRandomItemContentRelatedContent { + return v.Related +} + +func (v *CovariantInterfaceImplementationRandomItemVideo) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CovariantInterfaceImplementationRandomItemVideo + Next json.RawMessage `json:"next"` + Related []json.RawMessage `json:"related"` + graphql.NoUnmarshalJSON + } + firstPass.CovariantInterfaceImplementationRandomItemVideo = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Next + src := firstPass.Next + if len(src) != 0 && string(src) != "null" { + err = __unmarshalCovariantInterfaceImplementationRandomItemContentNextContent( + src, dst) + if err != nil { + return fmt.Errorf( + "Unable to unmarshal CovariantInterfaceImplementationRandomItemVideo.Next: %w", err) + } + } + } + + { + dst := &v.Related + src := firstPass.Related + *dst = make( + []CovariantInterfaceImplementationRandomItemContentRelatedContent, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + if len(src) != 0 && string(src) != "null" { + err = __unmarshalCovariantInterfaceImplementationRandomItemContentRelatedContent( + src, dst) + if err != nil { + return fmt.Errorf( + "Unable to unmarshal CovariantInterfaceImplementationRandomItemVideo.Related: %w", err) + } + } + } + } + return nil +} + +type __premarshalCovariantInterfaceImplementationRandomItemVideo struct { + Typename string `json:"__typename"` + + Id testutil.ID `json:"id"` + + Next json.RawMessage `json:"next"` + + Related []json.RawMessage `json:"related"` +} + +func (v *CovariantInterfaceImplementationRandomItemVideo) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CovariantInterfaceImplementationRandomItemVideo) __premarshalJSON() (*__premarshalCovariantInterfaceImplementationRandomItemVideo, error) { + var retval __premarshalCovariantInterfaceImplementationRandomItemVideo + + retval.Typename = v.Typename + retval.Id = v.Id + { + + dst := &retval.Next + src := v.Next + var err error + *dst, err = __marshalCovariantInterfaceImplementationRandomItemContentNextContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemVideo.Next: %w", err) + } + } + { + + dst := &retval.Related + src := v.Related + *dst = make( + []json.RawMessage, + len(src)) + for i, src := range src { + dst := &(*dst)[i] + var err error + *dst, err = __marshalCovariantInterfaceImplementationRandomItemContentRelatedContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationRandomItemVideo.Related: %w", err) + } + } + } + return &retval, nil +} + +// CovariantInterfaceImplementationResponse is returned by CovariantInterfaceImplementation on success. +type CovariantInterfaceImplementationResponse struct { + RandomItem CovariantInterfaceImplementationRandomItemContent `json:"-"` + Root CovariantInterfaceImplementationRootTopic `json:"root"` +} + +// GetRandomItem returns CovariantInterfaceImplementationResponse.RandomItem, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationResponse) GetRandomItem() CovariantInterfaceImplementationRandomItemContent { + return v.RandomItem +} + +// GetRoot returns CovariantInterfaceImplementationResponse.Root, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationResponse) GetRoot() CovariantInterfaceImplementationRootTopic { + return v.Root +} + +func (v *CovariantInterfaceImplementationResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CovariantInterfaceImplementationResponse + RandomItem json.RawMessage `json:"randomItem"` + graphql.NoUnmarshalJSON + } + firstPass.CovariantInterfaceImplementationResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.RandomItem + src := firstPass.RandomItem + if len(src) != 0 && string(src) != "null" { + err = __unmarshalCovariantInterfaceImplementationRandomItemContent( + src, dst) + if err != nil { + return fmt.Errorf( + "Unable to unmarshal CovariantInterfaceImplementationResponse.RandomItem: %w", err) + } + } + } + return nil +} + +type __premarshalCovariantInterfaceImplementationResponse struct { + RandomItem json.RawMessage `json:"randomItem"` + + Root CovariantInterfaceImplementationRootTopic `json:"root"` +} + +func (v *CovariantInterfaceImplementationResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CovariantInterfaceImplementationResponse) __premarshalJSON() (*__premarshalCovariantInterfaceImplementationResponse, error) { + var retval __premarshalCovariantInterfaceImplementationResponse + + { + + dst := &retval.RandomItem + src := v.RandomItem + var err error + *dst, err = __marshalCovariantInterfaceImplementationRandomItemContent( + &src) + if err != nil { + return nil, fmt.Errorf( + "Unable to marshal CovariantInterfaceImplementationResponse.RandomItem: %w", err) + } + } + retval.Root = v.Root + return &retval, nil +} + +// CovariantInterfaceImplementationRootTopic includes the requested fields of the GraphQL type Topic. +type CovariantInterfaceImplementationRootTopic struct { + ContentFieldsTopic `json:"-"` + TopicFields `json:"-"` + Next CovariantInterfaceImplementationRootTopicNextTopic `json:"next"` + Related []CovariantInterfaceImplementationRootTopicRelatedTopic `json:"related"` +} + +// GetNext returns CovariantInterfaceImplementationRootTopic.Next, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRootTopic) GetNext() CovariantInterfaceImplementationRootTopicNextTopic { + return v.Next +} + +// GetRelated returns CovariantInterfaceImplementationRootTopic.Related, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRootTopic) GetRelated() []CovariantInterfaceImplementationRootTopicRelatedTopic { + return v.Related +} + +func (v *CovariantInterfaceImplementationRootTopic) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CovariantInterfaceImplementationRootTopic + graphql.NoUnmarshalJSON + } + firstPass.CovariantInterfaceImplementationRootTopic = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.ContentFieldsTopic) + if err != nil { + return err + } + err = json.Unmarshal( + b, &v.TopicFields) + if err != nil { + return err + } + return nil +} + +type __premarshalCovariantInterfaceImplementationRootTopic struct { + Next CovariantInterfaceImplementationRootTopicNextTopic `json:"next"` + + Related []CovariantInterfaceImplementationRootTopicRelatedTopic `json:"related"` +} + +func (v *CovariantInterfaceImplementationRootTopic) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CovariantInterfaceImplementationRootTopic) __premarshalJSON() (*__premarshalCovariantInterfaceImplementationRootTopic, error) { + var retval __premarshalCovariantInterfaceImplementationRootTopic + + retval.Next = v.Next + retval.Related = v.Related + return &retval, nil +} + +// CovariantInterfaceImplementationRootTopicNextTopic includes the requested fields of the GraphQL type Topic. +type CovariantInterfaceImplementationRootTopicNextTopic struct { + TopicFields `json:"-"` +} + +// GetNext returns CovariantInterfaceImplementationRootTopicNextTopic.Next, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRootTopicNextTopic) GetNext() TopicFieldsNextTopic { + return v.TopicFields.Next +} + +// GetRelated returns CovariantInterfaceImplementationRootTopicNextTopic.Related, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRootTopicNextTopic) GetRelated() []TopicFieldsRelatedTopic { + return v.TopicFields.Related +} + +func (v *CovariantInterfaceImplementationRootTopicNextTopic) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CovariantInterfaceImplementationRootTopicNextTopic + graphql.NoUnmarshalJSON + } + firstPass.CovariantInterfaceImplementationRootTopicNextTopic = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.TopicFields) + if err != nil { + return err + } + return nil +} + +type __premarshalCovariantInterfaceImplementationRootTopicNextTopic struct { + Next TopicFieldsNextTopic `json:"next"` + + Related []TopicFieldsRelatedTopic `json:"related"` +} + +func (v *CovariantInterfaceImplementationRootTopicNextTopic) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CovariantInterfaceImplementationRootTopicNextTopic) __premarshalJSON() (*__premarshalCovariantInterfaceImplementationRootTopicNextTopic, error) { + var retval __premarshalCovariantInterfaceImplementationRootTopicNextTopic + + retval.Next = v.TopicFields.Next + retval.Related = v.TopicFields.Related + return &retval, nil +} + +// CovariantInterfaceImplementationRootTopicRelatedTopic includes the requested fields of the GraphQL type Topic. +type CovariantInterfaceImplementationRootTopicRelatedTopic struct { + TopicFields `json:"-"` +} + +// GetNext returns CovariantInterfaceImplementationRootTopicRelatedTopic.Next, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRootTopicRelatedTopic) GetNext() TopicFieldsNextTopic { + return v.TopicFields.Next +} + +// GetRelated returns CovariantInterfaceImplementationRootTopicRelatedTopic.Related, and is useful for accessing the field via an interface. +func (v *CovariantInterfaceImplementationRootTopicRelatedTopic) GetRelated() []TopicFieldsRelatedTopic { + return v.TopicFields.Related +} + +func (v *CovariantInterfaceImplementationRootTopicRelatedTopic) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *CovariantInterfaceImplementationRootTopicRelatedTopic + graphql.NoUnmarshalJSON + } + firstPass.CovariantInterfaceImplementationRootTopicRelatedTopic = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.TopicFields) + if err != nil { + return err + } + return nil +} + +type __premarshalCovariantInterfaceImplementationRootTopicRelatedTopic struct { + Next TopicFieldsNextTopic `json:"next"` + + Related []TopicFieldsRelatedTopic `json:"related"` +} + +func (v *CovariantInterfaceImplementationRootTopicRelatedTopic) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *CovariantInterfaceImplementationRootTopicRelatedTopic) __premarshalJSON() (*__premarshalCovariantInterfaceImplementationRootTopicRelatedTopic, error) { + var retval __premarshalCovariantInterfaceImplementationRootTopicRelatedTopic + + retval.Next = v.TopicFields.Next + retval.Related = v.TopicFields.Related + return &retval, nil +} + +// TopicFields includes the GraphQL fields of Topic requested by the fragment TopicFields. +type TopicFields struct { + Next TopicFieldsNextTopic `json:"next"` + Related []TopicFieldsRelatedTopic `json:"related"` +} + +// GetNext returns TopicFields.Next, and is useful for accessing the field via an interface. +func (v *TopicFields) GetNext() TopicFieldsNextTopic { return v.Next } + +// GetRelated returns TopicFields.Related, and is useful for accessing the field via an interface. +func (v *TopicFields) GetRelated() []TopicFieldsRelatedTopic { return v.Related } + +// TopicFieldsNextTopic includes the requested fields of the GraphQL type Topic. +type TopicFieldsNextTopic struct { + // ID is documented in the Content interface. + Id testutil.ID `json:"id"` +} + +// GetId returns TopicFieldsNextTopic.Id, and is useful for accessing the field via an interface. +func (v *TopicFieldsNextTopic) GetId() testutil.ID { return v.Id } + +// TopicFieldsRelatedTopic includes the requested fields of the GraphQL type Topic. +type TopicFieldsRelatedTopic struct { + // ID is documented in the Content interface. + Id testutil.ID `json:"id"` +} + +// GetId returns TopicFieldsRelatedTopic.Id, and is useful for accessing the field via an interface. +func (v *TopicFieldsRelatedTopic) GetId() testutil.ID { return v.Id } + +func CovariantInterfaceImplementation( + client graphql.Client, +) (*CovariantInterfaceImplementationResponse, error) { + req := &graphql.Request{ + OpName: "CovariantInterfaceImplementation", + Query: ` +query CovariantInterfaceImplementation { + randomItem { + __typename + id + next { + __typename + ... ContentFields + } + related { + __typename + ... ContentFields + } + } + root { + ... ContentFields + ... TopicFields + next { + ... TopicFields + } + related { + ... TopicFields + } + } +} +fragment ContentFields on Content { + next { + __typename + id + } + related { + __typename + id + } +} +fragment TopicFields on Topic { + next { + id + } + related { + id + } +} +`, + } + var err error + + var data CovariantInterfaceImplementationResponse + resp := &graphql.Response{Data: &data} + + err = client.MakeRequest( + nil, + req, + resp, + ) + + return &data, err +} + diff --git a/generate/testdata/snapshots/TestGenerate-CovariantInterfaceImplementation.graphql-CovariantInterfaceImplementation.graphql.json b/generate/testdata/snapshots/TestGenerate-CovariantInterfaceImplementation.graphql-CovariantInterfaceImplementation.graphql.json new file mode 100644 index 00000000..3646e3c9 --- /dev/null +++ b/generate/testdata/snapshots/TestGenerate-CovariantInterfaceImplementation.graphql-CovariantInterfaceImplementation.graphql.json @@ -0,0 +1,9 @@ +{ + "operations": [ + { + "operationName": "CovariantInterfaceImplementation", + "query": "\nquery CovariantInterfaceImplementation {\n\trandomItem {\n\t\t__typename\n\t\tid\n\t\tnext {\n\t\t\t__typename\n\t\t\t... ContentFields\n\t\t}\n\t\trelated {\n\t\t\t__typename\n\t\t\t... ContentFields\n\t\t}\n\t}\n\troot {\n\t\t... ContentFields\n\t\t... TopicFields\n\t\tnext {\n\t\t\t... TopicFields\n\t\t}\n\t\trelated {\n\t\t\t... TopicFields\n\t\t}\n\t}\n}\nfragment ContentFields on Content {\n\tnext {\n\t\t__typename\n\t\tid\n\t}\n\trelated {\n\t\t__typename\n\t\tid\n\t}\n}\nfragment TopicFields on Topic {\n\tnext {\n\t\tid\n\t}\n\trelated {\n\t\tid\n\t}\n}\n", + "sourceLocation": "testdata/queries/CovariantInterfaceImplementation.graphql" + } + ] +}