Add support for concrete-typed named fragments (#75)
## Summary:
In previous commits I added support to genqlient for interfaces and
inline fragments. This means the only query structures that remain are
named fragments and their spreads, e.g.
```
fragment MyFragment on MyType { myField }
query MyQuery { getMyType { ...MyFragment } }
```
Other than mere completionism, these are potentially useful for code
sharing: you can spread the same fragment multiple places; and then
genqlient can notice that and generate the same type for each. (They
can even be shared between different queries in the same package.)
In this commit I add support for named fragments of concrete
(object/struct, not interface) type, spread into either concrete or
abstract scope. For genqlient's purposes, these are a new "root"
type-name, just like each operation, and are then embedded into the
appropriate struct. (Using embeds allows their fields to be referenced
as fields of the containing type, if convenient. Further design
considerations are discussed in DESIGN.md.)
This requires new code in two main places (plus miscellaneous glue),
both nontrivial but neither particularly complex:
- We need to actually traverse both structures and generate the types
(in `convert.go`).
- We need to decide which fragments from this package to send to the
server, both for good hyigene and because GraphQL requires we send
only ones this query uses (in `generate.go`).
- We need a little new wiring for options -- because fragments can be
shared between queries they get their own toplevel options, rather
than inheriting the query's options.
Finally, this required slightly subtler changes to how we do
unmarshaling (in `types.go` and `unmarshal.go.tmpl`). Basically,
because embedded fields' methods, including `UnmarshalJSON`, get
promoted to the parent type, and because the JSON library ignores their
fields when shadowed by those of the parent type, we need a little bit
of special logic in each such parent type to do its own unmarshal and
then delegate to each embed. This is similar (and much simpler) to
what we did for interfaces, although it required some changes to the
"method-hiding" trick (used for both). It's only really necessary in
certain specific cases (namely when an embedded type has an
`UnmarshalJSON` method or a field with the same name as the embedder),
but it's easier to just generate it always. This is all described in
more detail inline.
This does not support fragments of abstract type, which have their own
complexities. I'll address those, which are now the only remaining
piece of #8, in a future commit.
Issue: https://github.com/Khan/genqlient/issues/8
## Test plan:
make check
Author: benjaminjkraft
Reviewers: dnerdy, benjaminjkraft, aberkan, MiguelCastillo
Required Reviewers:
Approved By: dnerdy
Checks: ✅ Lint, ✅ Test (1.17), ✅ Test (1.16), ✅ Test (1.15), ✅ Test (1.14), ✅ Test (1.13), ✅ 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/75
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
fragment QueryFragment on Query {
|
||||
...InnerQueryFragment
|
||||
}
|
||||
|
||||
fragment InnerQueryFragment on Query {
|
||||
randomItem {
|
||||
id name
|
||||
...VideoFields
|
||||
}
|
||||
randomLeaf {
|
||||
...VideoFields
|
||||
...MoreVideoFields
|
||||
}
|
||||
otherLeaf: randomLeaf {
|
||||
... on Video {
|
||||
...MoreVideoFields
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment VideoFields on Video {
|
||||
id name url duration thumbnail { id }
|
||||
}
|
||||
|
||||
# @genqlient(pointer: true)
|
||||
fragment MoreVideoFields on Video {
|
||||
id
|
||||
parent {
|
||||
name url
|
||||
# @genqlient(pointer: false)
|
||||
children {
|
||||
...VideoFields
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query ComplexNamedFragments {
|
||||
... on Query { ...QueryFragment }
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fragment VideoFields on Video {
|
||||
id name url duration thumbnail { id }
|
||||
}
|
||||
|
||||
query SimpleNamedFragment {
|
||||
randomItem {
|
||||
id name
|
||||
...VideoFields
|
||||
}
|
||||
randomLeaf {
|
||||
...VideoFields
|
||||
}
|
||||
}
|
||||
+15
-12
@@ -184,13 +184,12 @@ type ComplexInlineFragmentsNestedStuffTopic struct {
|
||||
|
||||
func (v *ComplexInlineFragmentsNestedStuffTopic) UnmarshalJSON(b []byte) error {
|
||||
|
||||
type ComplexInlineFragmentsNestedStuffTopicWrapper ComplexInlineFragmentsNestedStuffTopic
|
||||
|
||||
var firstPass struct {
|
||||
*ComplexInlineFragmentsNestedStuffTopicWrapper
|
||||
*ComplexInlineFragmentsNestedStuffTopic
|
||||
Children []json.RawMessage `json:"children"`
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.ComplexInlineFragmentsNestedStuffTopicWrapper = (*ComplexInlineFragmentsNestedStuffTopicWrapper)(v)
|
||||
firstPass.ComplexInlineFragmentsNestedStuffTopic = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
@@ -213,6 +212,7 @@ func (v *ComplexInlineFragmentsNestedStuffTopic) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -232,13 +232,12 @@ type ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTop
|
||||
|
||||
func (v *ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopic) UnmarshalJSON(b []byte) error {
|
||||
|
||||
type ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopicWrapper ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopic
|
||||
|
||||
var firstPass struct {
|
||||
*ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopicWrapper
|
||||
*ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopic
|
||||
Children []json.RawMessage `json:"children"`
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopicWrapper = (*ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopicWrapper)(v)
|
||||
firstPass.ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParentTopic = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
@@ -261,6 +260,7 @@ func (v *ComplexInlineFragmentsNestedStuffTopicChildrenArticleParentContentParen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -797,16 +797,15 @@ type ComplexInlineFragmentsResponse struct {
|
||||
|
||||
func (v *ComplexInlineFragmentsResponse) UnmarshalJSON(b []byte) error {
|
||||
|
||||
type ComplexInlineFragmentsResponseWrapper ComplexInlineFragmentsResponse
|
||||
|
||||
var firstPass struct {
|
||||
*ComplexInlineFragmentsResponseWrapper
|
||||
*ComplexInlineFragmentsResponse
|
||||
RandomItem json.RawMessage `json:"randomItem"`
|
||||
RepeatedStuff json.RawMessage `json:"repeatedStuff"`
|
||||
ConflictingStuff json.RawMessage `json:"conflictingStuff"`
|
||||
NestedStuff json.RawMessage `json:"nestedStuff"`
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.ComplexInlineFragmentsResponseWrapper = (*ComplexInlineFragmentsResponseWrapper)(v)
|
||||
firstPass.ComplexInlineFragmentsResponse = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
@@ -823,6 +822,7 @@ func (v *ComplexInlineFragmentsResponse) UnmarshalJSON(b []byte) error {
|
||||
"Unable to unmarshal ComplexInlineFragmentsResponse.RandomItem: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.RepeatedStuff
|
||||
raw := firstPass.RepeatedStuff
|
||||
@@ -833,6 +833,7 @@ func (v *ComplexInlineFragmentsResponse) UnmarshalJSON(b []byte) error {
|
||||
"Unable to unmarshal ComplexInlineFragmentsResponse.RepeatedStuff: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.ConflictingStuff
|
||||
raw := firstPass.ConflictingStuff
|
||||
@@ -843,6 +844,7 @@ func (v *ComplexInlineFragmentsResponse) UnmarshalJSON(b []byte) error {
|
||||
"Unable to unmarshal ComplexInlineFragmentsResponse.ConflictingStuff: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.NestedStuff
|
||||
raw := firstPass.NestedStuff
|
||||
@@ -853,6 +855,7 @@ func (v *ComplexInlineFragmentsResponse) UnmarshalJSON(b []byte) error {
|
||||
"Unable to unmarshal ComplexInlineFragmentsResponse.NestedStuff: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
+666
@@ -0,0 +1,666 @@
|
||||
package test
|
||||
|
||||
// Code generated by github.com/Khan/genqlient, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/Khan/genqlient/graphql"
|
||||
"github.com/Khan/genqlient/internal/testutil"
|
||||
)
|
||||
|
||||
// ComplexNamedFragmentsResponse is returned by ComplexNamedFragments on success.
|
||||
type ComplexNamedFragmentsResponse struct {
|
||||
QueryFragment `json:"-"`
|
||||
}
|
||||
|
||||
func (v *ComplexNamedFragmentsResponse) UnmarshalJSON(b []byte) error {
|
||||
|
||||
var firstPass struct {
|
||||
*ComplexNamedFragmentsResponse
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.ComplexNamedFragmentsResponse = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(b, &v.QueryFragment)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InnerQueryFragment includes the GraphQL fields of Query requested by the fragment InnerQueryFragment.
|
||||
type InnerQueryFragment struct {
|
||||
RandomItem InnerQueryFragmentRandomItemContent `json:"-"`
|
||||
RandomLeaf InnerQueryFragmentRandomLeafLeafContent `json:"-"`
|
||||
OtherLeaf InnerQueryFragmentOtherLeafLeafContent `json:"-"`
|
||||
}
|
||||
|
||||
func (v *InnerQueryFragment) UnmarshalJSON(b []byte) error {
|
||||
|
||||
var firstPass struct {
|
||||
*InnerQueryFragment
|
||||
RandomItem json.RawMessage `json:"randomItem"`
|
||||
RandomLeaf json.RawMessage `json:"randomLeaf"`
|
||||
OtherLeaf json.RawMessage `json:"otherLeaf"`
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.InnerQueryFragment = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.RandomItem
|
||||
raw := firstPass.RandomItem
|
||||
err = __unmarshalInnerQueryFragmentRandomItemContent(
|
||||
target, raw)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal InnerQueryFragment.RandomItem: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.RandomLeaf
|
||||
raw := firstPass.RandomLeaf
|
||||
err = __unmarshalInnerQueryFragmentRandomLeafLeafContent(
|
||||
target, raw)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal InnerQueryFragment.RandomLeaf: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.OtherLeaf
|
||||
raw := firstPass.OtherLeaf
|
||||
err = __unmarshalInnerQueryFragmentOtherLeafLeafContent(
|
||||
target, raw)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal InnerQueryFragment.OtherLeaf: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// InnerQueryFragmentOtherLeafArticle includes the requested fields of the GraphQL type Article.
|
||||
type InnerQueryFragmentOtherLeafArticle struct {
|
||||
Typename string `json:"__typename"`
|
||||
}
|
||||
|
||||
// InnerQueryFragmentOtherLeafLeafContent includes the requested fields of the GraphQL interface LeafContent.
|
||||
//
|
||||
// InnerQueryFragmentOtherLeafLeafContent is implemented by the following types:
|
||||
// InnerQueryFragmentOtherLeafArticle
|
||||
// InnerQueryFragmentOtherLeafVideo
|
||||
//
|
||||
// The GraphQL type's documentation follows.
|
||||
//
|
||||
// LeafContent represents content items that can't have child-nodes.
|
||||
type InnerQueryFragmentOtherLeafLeafContent interface {
|
||||
implementsGraphQLInterfaceInnerQueryFragmentOtherLeafLeafContent()
|
||||
// GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values).
|
||||
GetTypename() string
|
||||
}
|
||||
|
||||
func (v *InnerQueryFragmentOtherLeafArticle) implementsGraphQLInterfaceInnerQueryFragmentOtherLeafLeafContent() {
|
||||
}
|
||||
|
||||
// GetTypename is a part of, and documented with, the interface InnerQueryFragmentOtherLeafLeafContent.
|
||||
func (v *InnerQueryFragmentOtherLeafArticle) GetTypename() string { return v.Typename }
|
||||
|
||||
func (v *InnerQueryFragmentOtherLeafVideo) implementsGraphQLInterfaceInnerQueryFragmentOtherLeafLeafContent() {
|
||||
}
|
||||
|
||||
// GetTypename is a part of, and documented with, the interface InnerQueryFragmentOtherLeafLeafContent.
|
||||
func (v *InnerQueryFragmentOtherLeafVideo) GetTypename() string { return v.Typename }
|
||||
|
||||
func __unmarshalInnerQueryFragmentOtherLeafLeafContent(v *InnerQueryFragmentOtherLeafLeafContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
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(InnerQueryFragmentOtherLeafArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
case "Video":
|
||||
*v = new(InnerQueryFragmentOtherLeafVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing LeafContent.__typename")
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
`Unexpected concrete type for InnerQueryFragmentOtherLeafLeafContent: "%v"`, tn.TypeName)
|
||||
}
|
||||
}
|
||||
|
||||
// InnerQueryFragmentOtherLeafVideo includes the requested fields of the GraphQL type Video.
|
||||
type InnerQueryFragmentOtherLeafVideo struct {
|
||||
Typename string `json:"__typename"`
|
||||
MoreVideoFields `json:"-"`
|
||||
}
|
||||
|
||||
func (v *InnerQueryFragmentOtherLeafVideo) UnmarshalJSON(b []byte) error {
|
||||
|
||||
var firstPass struct {
|
||||
*InnerQueryFragmentOtherLeafVideo
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.InnerQueryFragmentOtherLeafVideo = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(b, &v.MoreVideoFields)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InnerQueryFragmentRandomItemArticle includes the requested fields of the GraphQL type Article.
|
||||
type InnerQueryFragmentRandomItemArticle struct {
|
||||
Typename string `json:"__typename"`
|
||||
// ID is the identifier of the content.
|
||||
Id testutil.ID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// InnerQueryFragmentRandomItemContent includes the requested fields of the GraphQL interface Content.
|
||||
//
|
||||
// InnerQueryFragmentRandomItemContent is implemented by the following types:
|
||||
// InnerQueryFragmentRandomItemArticle
|
||||
// InnerQueryFragmentRandomItemVideo
|
||||
// InnerQueryFragmentRandomItemTopic
|
||||
//
|
||||
// The GraphQL type's documentation follows.
|
||||
//
|
||||
// Content is implemented by various types like Article, Video, and Topic.
|
||||
type InnerQueryFragmentRandomItemContent interface {
|
||||
implementsGraphQLInterfaceInnerQueryFragmentRandomItemContent()
|
||||
// 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 *InnerQueryFragmentRandomItemArticle) implementsGraphQLInterfaceInnerQueryFragmentRandomItemContent() {
|
||||
}
|
||||
|
||||
// GetTypename is a part of, and documented with, the interface InnerQueryFragmentRandomItemContent.
|
||||
func (v *InnerQueryFragmentRandomItemArticle) GetTypename() string { return v.Typename }
|
||||
|
||||
// GetId is a part of, and documented with, the interface InnerQueryFragmentRandomItemContent.
|
||||
func (v *InnerQueryFragmentRandomItemArticle) GetId() testutil.ID { return v.Id }
|
||||
|
||||
// GetName is a part of, and documented with, the interface InnerQueryFragmentRandomItemContent.
|
||||
func (v *InnerQueryFragmentRandomItemArticle) GetName() string { return v.Name }
|
||||
|
||||
func (v *InnerQueryFragmentRandomItemVideo) implementsGraphQLInterfaceInnerQueryFragmentRandomItemContent() {
|
||||
}
|
||||
|
||||
// GetTypename is a part of, and documented with, the interface InnerQueryFragmentRandomItemContent.
|
||||
func (v *InnerQueryFragmentRandomItemVideo) GetTypename() string { return v.Typename }
|
||||
|
||||
// GetId is a part of, and documented with, the interface InnerQueryFragmentRandomItemContent.
|
||||
func (v *InnerQueryFragmentRandomItemVideo) GetId() testutil.ID { return v.Id }
|
||||
|
||||
// GetName is a part of, and documented with, the interface InnerQueryFragmentRandomItemContent.
|
||||
func (v *InnerQueryFragmentRandomItemVideo) GetName() string { return v.Name }
|
||||
|
||||
func (v *InnerQueryFragmentRandomItemTopic) implementsGraphQLInterfaceInnerQueryFragmentRandomItemContent() {
|
||||
}
|
||||
|
||||
// GetTypename is a part of, and documented with, the interface InnerQueryFragmentRandomItemContent.
|
||||
func (v *InnerQueryFragmentRandomItemTopic) GetTypename() string { return v.Typename }
|
||||
|
||||
// GetId is a part of, and documented with, the interface InnerQueryFragmentRandomItemContent.
|
||||
func (v *InnerQueryFragmentRandomItemTopic) GetId() testutil.ID { return v.Id }
|
||||
|
||||
// GetName is a part of, and documented with, the interface InnerQueryFragmentRandomItemContent.
|
||||
func (v *InnerQueryFragmentRandomItemTopic) GetName() string { return v.Name }
|
||||
|
||||
func __unmarshalInnerQueryFragmentRandomItemContent(v *InnerQueryFragmentRandomItemContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
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(InnerQueryFragmentRandomItemArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
case "Video":
|
||||
*v = new(InnerQueryFragmentRandomItemVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
case "Topic":
|
||||
*v = new(InnerQueryFragmentRandomItemTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
`Unexpected concrete type for InnerQueryFragmentRandomItemContent: "%v"`, tn.TypeName)
|
||||
}
|
||||
}
|
||||
|
||||
// InnerQueryFragmentRandomItemTopic includes the requested fields of the GraphQL type Topic.
|
||||
type InnerQueryFragmentRandomItemTopic struct {
|
||||
Typename string `json:"__typename"`
|
||||
// ID is the identifier of the content.
|
||||
Id testutil.ID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// InnerQueryFragmentRandomItemVideo includes the requested fields of the GraphQL type Video.
|
||||
type InnerQueryFragmentRandomItemVideo struct {
|
||||
Typename string `json:"__typename"`
|
||||
// ID is the identifier of the content.
|
||||
Id testutil.ID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
VideoFields `json:"-"`
|
||||
}
|
||||
|
||||
func (v *InnerQueryFragmentRandomItemVideo) UnmarshalJSON(b []byte) error {
|
||||
|
||||
var firstPass struct {
|
||||
*InnerQueryFragmentRandomItemVideo
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.InnerQueryFragmentRandomItemVideo = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(b, &v.VideoFields)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InnerQueryFragmentRandomLeafArticle includes the requested fields of the GraphQL type Article.
|
||||
type InnerQueryFragmentRandomLeafArticle struct {
|
||||
Typename string `json:"__typename"`
|
||||
}
|
||||
|
||||
// InnerQueryFragmentRandomLeafLeafContent includes the requested fields of the GraphQL interface LeafContent.
|
||||
//
|
||||
// InnerQueryFragmentRandomLeafLeafContent is implemented by the following types:
|
||||
// InnerQueryFragmentRandomLeafArticle
|
||||
// InnerQueryFragmentRandomLeafVideo
|
||||
//
|
||||
// The GraphQL type's documentation follows.
|
||||
//
|
||||
// LeafContent represents content items that can't have child-nodes.
|
||||
type InnerQueryFragmentRandomLeafLeafContent interface {
|
||||
implementsGraphQLInterfaceInnerQueryFragmentRandomLeafLeafContent()
|
||||
// GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values).
|
||||
GetTypename() string
|
||||
}
|
||||
|
||||
func (v *InnerQueryFragmentRandomLeafArticle) implementsGraphQLInterfaceInnerQueryFragmentRandomLeafLeafContent() {
|
||||
}
|
||||
|
||||
// GetTypename is a part of, and documented with, the interface InnerQueryFragmentRandomLeafLeafContent.
|
||||
func (v *InnerQueryFragmentRandomLeafArticle) GetTypename() string { return v.Typename }
|
||||
|
||||
func (v *InnerQueryFragmentRandomLeafVideo) implementsGraphQLInterfaceInnerQueryFragmentRandomLeafLeafContent() {
|
||||
}
|
||||
|
||||
// GetTypename is a part of, and documented with, the interface InnerQueryFragmentRandomLeafLeafContent.
|
||||
func (v *InnerQueryFragmentRandomLeafVideo) GetTypename() string { return v.Typename }
|
||||
|
||||
func __unmarshalInnerQueryFragmentRandomLeafLeafContent(v *InnerQueryFragmentRandomLeafLeafContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
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(InnerQueryFragmentRandomLeafArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
case "Video":
|
||||
*v = new(InnerQueryFragmentRandomLeafVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing LeafContent.__typename")
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
`Unexpected concrete type for InnerQueryFragmentRandomLeafLeafContent: "%v"`, tn.TypeName)
|
||||
}
|
||||
}
|
||||
|
||||
// InnerQueryFragmentRandomLeafVideo includes the requested fields of the GraphQL type Video.
|
||||
type InnerQueryFragmentRandomLeafVideo struct {
|
||||
Typename string `json:"__typename"`
|
||||
VideoFields `json:"-"`
|
||||
MoreVideoFields `json:"-"`
|
||||
}
|
||||
|
||||
func (v *InnerQueryFragmentRandomLeafVideo) UnmarshalJSON(b []byte) error {
|
||||
|
||||
var firstPass struct {
|
||||
*InnerQueryFragmentRandomLeafVideo
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.InnerQueryFragmentRandomLeafVideo = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(b, &v.VideoFields)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(b, &v.MoreVideoFields)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MoreVideoFields includes the GraphQL fields of Video requested by the fragment MoreVideoFields.
|
||||
type MoreVideoFields struct {
|
||||
// ID is documented in the Content interface.
|
||||
Id *testutil.ID `json:"id"`
|
||||
Parent *MoreVideoFieldsParentTopic `json:"parent"`
|
||||
}
|
||||
|
||||
// MoreVideoFieldsParentTopic includes the requested fields of the GraphQL type Topic.
|
||||
type MoreVideoFieldsParentTopic struct {
|
||||
Name *string `json:"name"`
|
||||
Url *string `json:"url"`
|
||||
Children []MoreVideoFieldsParentTopicChildrenContent `json:"-"`
|
||||
}
|
||||
|
||||
func (v *MoreVideoFieldsParentTopic) UnmarshalJSON(b []byte) error {
|
||||
|
||||
var firstPass struct {
|
||||
*MoreVideoFieldsParentTopic
|
||||
Children []json.RawMessage `json:"children"`
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.MoreVideoFieldsParentTopic = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.Children
|
||||
raw := firstPass.Children
|
||||
*target = make(
|
||||
[]MoreVideoFieldsParentTopicChildrenContent,
|
||||
len(raw))
|
||||
for i, raw := range raw {
|
||||
target := &(*target)[i]
|
||||
err = __unmarshalMoreVideoFieldsParentTopicChildrenContent(
|
||||
target, raw)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal MoreVideoFieldsParentTopic.Children: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MoreVideoFieldsParentTopicChildrenArticle includes the requested fields of the GraphQL type Article.
|
||||
type MoreVideoFieldsParentTopicChildrenArticle struct {
|
||||
Typename *string `json:"__typename"`
|
||||
}
|
||||
|
||||
// MoreVideoFieldsParentTopicChildrenContent includes the requested fields of the GraphQL interface Content.
|
||||
//
|
||||
// MoreVideoFieldsParentTopicChildrenContent is implemented by the following types:
|
||||
// MoreVideoFieldsParentTopicChildrenArticle
|
||||
// MoreVideoFieldsParentTopicChildrenVideo
|
||||
// MoreVideoFieldsParentTopicChildrenTopic
|
||||
//
|
||||
// The GraphQL type's documentation follows.
|
||||
//
|
||||
// Content is implemented by various types like Article, Video, and Topic.
|
||||
type MoreVideoFieldsParentTopicChildrenContent interface {
|
||||
implementsGraphQLInterfaceMoreVideoFieldsParentTopicChildrenContent()
|
||||
// GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values).
|
||||
GetTypename() *string
|
||||
}
|
||||
|
||||
func (v *MoreVideoFieldsParentTopicChildrenArticle) implementsGraphQLInterfaceMoreVideoFieldsParentTopicChildrenContent() {
|
||||
}
|
||||
|
||||
// GetTypename is a part of, and documented with, the interface MoreVideoFieldsParentTopicChildrenContent.
|
||||
func (v *MoreVideoFieldsParentTopicChildrenArticle) GetTypename() *string { return v.Typename }
|
||||
|
||||
func (v *MoreVideoFieldsParentTopicChildrenVideo) implementsGraphQLInterfaceMoreVideoFieldsParentTopicChildrenContent() {
|
||||
}
|
||||
|
||||
// GetTypename is a part of, and documented with, the interface MoreVideoFieldsParentTopicChildrenContent.
|
||||
func (v *MoreVideoFieldsParentTopicChildrenVideo) GetTypename() *string { return v.Typename }
|
||||
|
||||
func (v *MoreVideoFieldsParentTopicChildrenTopic) implementsGraphQLInterfaceMoreVideoFieldsParentTopicChildrenContent() {
|
||||
}
|
||||
|
||||
// GetTypename is a part of, and documented with, the interface MoreVideoFieldsParentTopicChildrenContent.
|
||||
func (v *MoreVideoFieldsParentTopicChildrenTopic) GetTypename() *string { return v.Typename }
|
||||
|
||||
func __unmarshalMoreVideoFieldsParentTopicChildrenContent(v *MoreVideoFieldsParentTopicChildrenContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
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(MoreVideoFieldsParentTopicChildrenArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
case "Video":
|
||||
*v = new(MoreVideoFieldsParentTopicChildrenVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
case "Topic":
|
||||
*v = new(MoreVideoFieldsParentTopicChildrenTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
`Unexpected concrete type for MoreVideoFieldsParentTopicChildrenContent: "%v"`, tn.TypeName)
|
||||
}
|
||||
}
|
||||
|
||||
// MoreVideoFieldsParentTopicChildrenTopic includes the requested fields of the GraphQL type Topic.
|
||||
type MoreVideoFieldsParentTopicChildrenTopic struct {
|
||||
Typename *string `json:"__typename"`
|
||||
}
|
||||
|
||||
// MoreVideoFieldsParentTopicChildrenVideo includes the requested fields of the GraphQL type Video.
|
||||
type MoreVideoFieldsParentTopicChildrenVideo struct {
|
||||
Typename *string `json:"__typename"`
|
||||
VideoFields `json:"-"`
|
||||
}
|
||||
|
||||
func (v *MoreVideoFieldsParentTopicChildrenVideo) UnmarshalJSON(b []byte) error {
|
||||
|
||||
var firstPass struct {
|
||||
*MoreVideoFieldsParentTopicChildrenVideo
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.MoreVideoFieldsParentTopicChildrenVideo = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(b, &v.VideoFields)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// QueryFragment includes the GraphQL fields of Query requested by the fragment QueryFragment.
|
||||
type QueryFragment struct {
|
||||
InnerQueryFragment `json:"-"`
|
||||
}
|
||||
|
||||
func (v *QueryFragment) UnmarshalJSON(b []byte) error {
|
||||
|
||||
var firstPass struct {
|
||||
*QueryFragment
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.QueryFragment = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(b, &v.InnerQueryFragment)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// VideoFields includes the GraphQL fields of Video requested by the fragment VideoFields.
|
||||
type VideoFields struct {
|
||||
// ID is documented in the Content interface.
|
||||
Id testutil.ID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Url string `json:"url"`
|
||||
Duration int `json:"duration"`
|
||||
Thumbnail VideoFieldsThumbnail `json:"thumbnail"`
|
||||
}
|
||||
|
||||
// VideoFieldsThumbnail includes the requested fields of the GraphQL type Thumbnail.
|
||||
type VideoFieldsThumbnail struct {
|
||||
Id testutil.ID `json:"id"`
|
||||
}
|
||||
|
||||
func ComplexNamedFragments(
|
||||
client graphql.Client,
|
||||
) (*ComplexNamedFragmentsResponse, error) {
|
||||
var err error
|
||||
|
||||
var retval ComplexNamedFragmentsResponse
|
||||
err = client.MakeRequest(
|
||||
nil,
|
||||
"ComplexNamedFragments",
|
||||
`
|
||||
query ComplexNamedFragments {
|
||||
... on Query {
|
||||
... QueryFragment
|
||||
}
|
||||
}
|
||||
fragment QueryFragment on Query {
|
||||
... InnerQueryFragment
|
||||
}
|
||||
fragment InnerQueryFragment on Query {
|
||||
randomItem {
|
||||
__typename
|
||||
id
|
||||
name
|
||||
... VideoFields
|
||||
}
|
||||
randomLeaf {
|
||||
__typename
|
||||
... VideoFields
|
||||
... MoreVideoFields
|
||||
}
|
||||
otherLeaf: randomLeaf {
|
||||
__typename
|
||||
... on Video {
|
||||
... MoreVideoFields
|
||||
}
|
||||
}
|
||||
}
|
||||
fragment VideoFields on Video {
|
||||
id
|
||||
name
|
||||
url
|
||||
duration
|
||||
thumbnail {
|
||||
id
|
||||
}
|
||||
}
|
||||
fragment MoreVideoFields on Video {
|
||||
id
|
||||
parent {
|
||||
name
|
||||
url
|
||||
children {
|
||||
__typename
|
||||
... VideoFields
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
&retval,
|
||||
nil,
|
||||
)
|
||||
return &retval, err
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"operations": [
|
||||
{
|
||||
"operationName": "ComplexNamedFragments",
|
||||
"query": "\nquery ComplexNamedFragments {\n\t... on Query {\n\t\t... QueryFragment\n\t}\n}\nfragment QueryFragment on Query {\n\t... InnerQueryFragment\n}\nfragment InnerQueryFragment on Query {\n\trandomItem {\n\t\t__typename\n\t\tid\n\t\tname\n\t\t... VideoFields\n\t}\n\trandomLeaf {\n\t\t__typename\n\t\t... VideoFields\n\t\t... MoreVideoFields\n\t}\n\totherLeaf: randomLeaf {\n\t\t__typename\n\t\t... on Video {\n\t\t\t... MoreVideoFields\n\t\t}\n\t}\n}\nfragment VideoFields on Video {\n\tid\n\tname\n\turl\n\tduration\n\tthumbnail {\n\t\tid\n\t}\n}\nfragment MoreVideoFields on Video {\n\tid\n\tparent {\n\t\tname\n\t\turl\n\t\tchildren {\n\t\t\t__typename\n\t\t\t... VideoFields\n\t\t}\n\t}\n}\n",
|
||||
"sourceLocation": "testdata/queries/ComplexNamedFragments.graphql"
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+8
-8
@@ -26,13 +26,12 @@ type InterfaceListFieldRootTopic struct {
|
||||
|
||||
func (v *InterfaceListFieldRootTopic) UnmarshalJSON(b []byte) error {
|
||||
|
||||
type InterfaceListFieldRootTopicWrapper InterfaceListFieldRootTopic
|
||||
|
||||
var firstPass struct {
|
||||
*InterfaceListFieldRootTopicWrapper
|
||||
*InterfaceListFieldRootTopic
|
||||
Children []json.RawMessage `json:"children"`
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.InterfaceListFieldRootTopicWrapper = (*InterfaceListFieldRootTopicWrapper)(v)
|
||||
firstPass.InterfaceListFieldRootTopic = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
@@ -55,6 +54,7 @@ func (v *InterfaceListFieldRootTopic) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -183,13 +183,12 @@ type InterfaceListFieldWithPointerTopic struct {
|
||||
|
||||
func (v *InterfaceListFieldWithPointerTopic) UnmarshalJSON(b []byte) error {
|
||||
|
||||
type InterfaceListFieldWithPointerTopicWrapper InterfaceListFieldWithPointerTopic
|
||||
|
||||
var firstPass struct {
|
||||
*InterfaceListFieldWithPointerTopicWrapper
|
||||
*InterfaceListFieldWithPointerTopic
|
||||
Children []json.RawMessage `json:"children"`
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.InterfaceListFieldWithPointerTopicWrapper = (*InterfaceListFieldWithPointerTopicWrapper)(v)
|
||||
firstPass.InterfaceListFieldWithPointerTopic = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
@@ -212,6 +211,7 @@ func (v *InterfaceListFieldWithPointerTopic) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
+5
-4
@@ -151,14 +151,13 @@ type InterfaceListOfListOfListsFieldResponse struct {
|
||||
|
||||
func (v *InterfaceListOfListOfListsFieldResponse) UnmarshalJSON(b []byte) error {
|
||||
|
||||
type InterfaceListOfListOfListsFieldResponseWrapper InterfaceListOfListOfListsFieldResponse
|
||||
|
||||
var firstPass struct {
|
||||
*InterfaceListOfListOfListsFieldResponseWrapper
|
||||
*InterfaceListOfListOfListsFieldResponse
|
||||
ListOfListsOfListsOfContent [][][]json.RawMessage `json:"listOfListsOfListsOfContent"`
|
||||
WithPointer [][][]json.RawMessage `json:"withPointer"`
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.InterfaceListOfListOfListsFieldResponseWrapper = (*InterfaceListOfListOfListsFieldResponseWrapper)(v)
|
||||
firstPass.InterfaceListOfListOfListsFieldResponse = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
@@ -193,6 +192,7 @@ func (v *InterfaceListOfListOfListsFieldResponse) UnmarshalJSON(b []byte) error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.WithPointer
|
||||
raw := firstPass.WithPointer
|
||||
@@ -222,6 +222,7 @@ func (v *InterfaceListOfListOfListsFieldResponse) UnmarshalJSON(b []byte) error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Vendored
+8
-8
@@ -24,13 +24,12 @@ type InterfaceNestingRootTopic struct {
|
||||
|
||||
func (v *InterfaceNestingRootTopic) UnmarshalJSON(b []byte) error {
|
||||
|
||||
type InterfaceNestingRootTopicWrapper InterfaceNestingRootTopic
|
||||
|
||||
var firstPass struct {
|
||||
*InterfaceNestingRootTopicWrapper
|
||||
*InterfaceNestingRootTopic
|
||||
Children []json.RawMessage `json:"children"`
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.InterfaceNestingRootTopicWrapper = (*InterfaceNestingRootTopicWrapper)(v)
|
||||
firstPass.InterfaceNestingRootTopic = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
@@ -53,6 +52,7 @@ func (v *InterfaceNestingRootTopic) UnmarshalJSON(b []byte) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -170,13 +170,12 @@ type InterfaceNestingRootTopicChildrenContentParentTopic struct {
|
||||
|
||||
func (v *InterfaceNestingRootTopicChildrenContentParentTopic) UnmarshalJSON(b []byte) error {
|
||||
|
||||
type InterfaceNestingRootTopicChildrenContentParentTopicWrapper InterfaceNestingRootTopicChildrenContentParentTopic
|
||||
|
||||
var firstPass struct {
|
||||
*InterfaceNestingRootTopicChildrenContentParentTopicWrapper
|
||||
*InterfaceNestingRootTopicChildrenContentParentTopic
|
||||
Children []json.RawMessage `json:"children"`
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.InterfaceNestingRootTopicChildrenContentParentTopicWrapper = (*InterfaceNestingRootTopicChildrenContentParentTopicWrapper)(v)
|
||||
firstPass.InterfaceNestingRootTopicChildrenContentParentTopic = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
@@ -199,6 +198,7 @@ func (v *InterfaceNestingRootTopicChildrenContentParentTopic) UnmarshalJSON(b []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -256,15 +256,14 @@ type InterfaceNoFragmentsQueryResponse struct {
|
||||
|
||||
func (v *InterfaceNoFragmentsQueryResponse) UnmarshalJSON(b []byte) error {
|
||||
|
||||
type InterfaceNoFragmentsQueryResponseWrapper InterfaceNoFragmentsQueryResponse
|
||||
|
||||
var firstPass struct {
|
||||
*InterfaceNoFragmentsQueryResponseWrapper
|
||||
*InterfaceNoFragmentsQueryResponse
|
||||
RandomItem json.RawMessage `json:"randomItem"`
|
||||
RandomItemWithTypeName json.RawMessage `json:"randomItemWithTypeName"`
|
||||
WithPointer json.RawMessage `json:"withPointer"`
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.InterfaceNoFragmentsQueryResponseWrapper = (*InterfaceNoFragmentsQueryResponseWrapper)(v)
|
||||
firstPass.InterfaceNoFragmentsQueryResponse = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
@@ -281,6 +280,7 @@ func (v *InterfaceNoFragmentsQueryResponse) UnmarshalJSON(b []byte) error {
|
||||
"Unable to unmarshal InterfaceNoFragmentsQueryResponse.RandomItem: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.RandomItemWithTypeName
|
||||
raw := firstPass.RandomItemWithTypeName
|
||||
@@ -291,6 +291,7 @@ func (v *InterfaceNoFragmentsQueryResponse) UnmarshalJSON(b []byte) error {
|
||||
"Unable to unmarshal InterfaceNoFragmentsQueryResponse.RandomItemWithTypeName: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.WithPointer
|
||||
raw := firstPass.WithPointer
|
||||
@@ -302,6 +303,7 @@ func (v *InterfaceNoFragmentsQueryResponse) UnmarshalJSON(b []byte) error {
|
||||
"Unable to unmarshal InterfaceNoFragmentsQueryResponse.WithPointer: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -134,13 +134,12 @@ type SimpleInlineFragmentResponse struct {
|
||||
|
||||
func (v *SimpleInlineFragmentResponse) UnmarshalJSON(b []byte) error {
|
||||
|
||||
type SimpleInlineFragmentResponseWrapper SimpleInlineFragmentResponse
|
||||
|
||||
var firstPass struct {
|
||||
*SimpleInlineFragmentResponseWrapper
|
||||
*SimpleInlineFragmentResponse
|
||||
RandomItem json.RawMessage `json:"randomItem"`
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.SimpleInlineFragmentResponseWrapper = (*SimpleInlineFragmentResponseWrapper)(v)
|
||||
firstPass.SimpleInlineFragmentResponse = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
@@ -157,6 +156,7 @@ func (v *SimpleInlineFragmentResponse) UnmarshalJSON(b []byte) error {
|
||||
"Unable to unmarshal SimpleInlineFragmentResponse.RandomItem: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Vendored
+334
@@ -0,0 +1,334 @@
|
||||
package test
|
||||
|
||||
// Code generated by github.com/Khan/genqlient, DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/Khan/genqlient/graphql"
|
||||
"github.com/Khan/genqlient/internal/testutil"
|
||||
)
|
||||
|
||||
// SimpleNamedFragmentRandomItemArticle includes the requested fields of the GraphQL type Article.
|
||||
type SimpleNamedFragmentRandomItemArticle struct {
|
||||
Typename string `json:"__typename"`
|
||||
// ID is the identifier of the content.
|
||||
Id testutil.ID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// SimpleNamedFragmentRandomItemContent includes the requested fields of the GraphQL interface Content.
|
||||
//
|
||||
// SimpleNamedFragmentRandomItemContent is implemented by the following types:
|
||||
// SimpleNamedFragmentRandomItemArticle
|
||||
// SimpleNamedFragmentRandomItemVideo
|
||||
// SimpleNamedFragmentRandomItemTopic
|
||||
//
|
||||
// The GraphQL type's documentation follows.
|
||||
//
|
||||
// Content is implemented by various types like Article, Video, and Topic.
|
||||
type SimpleNamedFragmentRandomItemContent interface {
|
||||
implementsGraphQLInterfaceSimpleNamedFragmentRandomItemContent()
|
||||
// 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 *SimpleNamedFragmentRandomItemArticle) implementsGraphQLInterfaceSimpleNamedFragmentRandomItemContent() {
|
||||
}
|
||||
|
||||
// GetTypename is a part of, and documented with, the interface SimpleNamedFragmentRandomItemContent.
|
||||
func (v *SimpleNamedFragmentRandomItemArticle) GetTypename() string { return v.Typename }
|
||||
|
||||
// GetId is a part of, and documented with, the interface SimpleNamedFragmentRandomItemContent.
|
||||
func (v *SimpleNamedFragmentRandomItemArticle) GetId() testutil.ID { return v.Id }
|
||||
|
||||
// GetName is a part of, and documented with, the interface SimpleNamedFragmentRandomItemContent.
|
||||
func (v *SimpleNamedFragmentRandomItemArticle) GetName() string { return v.Name }
|
||||
|
||||
func (v *SimpleNamedFragmentRandomItemVideo) implementsGraphQLInterfaceSimpleNamedFragmentRandomItemContent() {
|
||||
}
|
||||
|
||||
// GetTypename is a part of, and documented with, the interface SimpleNamedFragmentRandomItemContent.
|
||||
func (v *SimpleNamedFragmentRandomItemVideo) GetTypename() string { return v.Typename }
|
||||
|
||||
// GetId is a part of, and documented with, the interface SimpleNamedFragmentRandomItemContent.
|
||||
func (v *SimpleNamedFragmentRandomItemVideo) GetId() testutil.ID { return v.Id }
|
||||
|
||||
// GetName is a part of, and documented with, the interface SimpleNamedFragmentRandomItemContent.
|
||||
func (v *SimpleNamedFragmentRandomItemVideo) GetName() string { return v.Name }
|
||||
|
||||
func (v *SimpleNamedFragmentRandomItemTopic) implementsGraphQLInterfaceSimpleNamedFragmentRandomItemContent() {
|
||||
}
|
||||
|
||||
// GetTypename is a part of, and documented with, the interface SimpleNamedFragmentRandomItemContent.
|
||||
func (v *SimpleNamedFragmentRandomItemTopic) GetTypename() string { return v.Typename }
|
||||
|
||||
// GetId is a part of, and documented with, the interface SimpleNamedFragmentRandomItemContent.
|
||||
func (v *SimpleNamedFragmentRandomItemTopic) GetId() testutil.ID { return v.Id }
|
||||
|
||||
// GetName is a part of, and documented with, the interface SimpleNamedFragmentRandomItemContent.
|
||||
func (v *SimpleNamedFragmentRandomItemTopic) GetName() string { return v.Name }
|
||||
|
||||
func __unmarshalSimpleNamedFragmentRandomItemContent(v *SimpleNamedFragmentRandomItemContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
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(SimpleNamedFragmentRandomItemArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
case "Video":
|
||||
*v = new(SimpleNamedFragmentRandomItemVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
case "Topic":
|
||||
*v = new(SimpleNamedFragmentRandomItemTopic)
|
||||
return json.Unmarshal(m, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing Content.__typename")
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
`Unexpected concrete type for SimpleNamedFragmentRandomItemContent: "%v"`, tn.TypeName)
|
||||
}
|
||||
}
|
||||
|
||||
// SimpleNamedFragmentRandomItemTopic includes the requested fields of the GraphQL type Topic.
|
||||
type SimpleNamedFragmentRandomItemTopic struct {
|
||||
Typename string `json:"__typename"`
|
||||
// ID is the identifier of the content.
|
||||
Id testutil.ID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// SimpleNamedFragmentRandomItemVideo includes the requested fields of the GraphQL type Video.
|
||||
type SimpleNamedFragmentRandomItemVideo struct {
|
||||
Typename string `json:"__typename"`
|
||||
// ID is the identifier of the content.
|
||||
Id testutil.ID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
VideoFields `json:"-"`
|
||||
}
|
||||
|
||||
func (v *SimpleNamedFragmentRandomItemVideo) UnmarshalJSON(b []byte) error {
|
||||
|
||||
var firstPass struct {
|
||||
*SimpleNamedFragmentRandomItemVideo
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.SimpleNamedFragmentRandomItemVideo = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(b, &v.VideoFields)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SimpleNamedFragmentRandomLeafArticle includes the requested fields of the GraphQL type Article.
|
||||
type SimpleNamedFragmentRandomLeafArticle struct {
|
||||
Typename string `json:"__typename"`
|
||||
}
|
||||
|
||||
// SimpleNamedFragmentRandomLeafLeafContent includes the requested fields of the GraphQL interface LeafContent.
|
||||
//
|
||||
// SimpleNamedFragmentRandomLeafLeafContent is implemented by the following types:
|
||||
// SimpleNamedFragmentRandomLeafArticle
|
||||
// SimpleNamedFragmentRandomLeafVideo
|
||||
//
|
||||
// The GraphQL type's documentation follows.
|
||||
//
|
||||
// LeafContent represents content items that can't have child-nodes.
|
||||
type SimpleNamedFragmentRandomLeafLeafContent interface {
|
||||
implementsGraphQLInterfaceSimpleNamedFragmentRandomLeafLeafContent()
|
||||
// GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values).
|
||||
GetTypename() string
|
||||
}
|
||||
|
||||
func (v *SimpleNamedFragmentRandomLeafArticle) implementsGraphQLInterfaceSimpleNamedFragmentRandomLeafLeafContent() {
|
||||
}
|
||||
|
||||
// GetTypename is a part of, and documented with, the interface SimpleNamedFragmentRandomLeafLeafContent.
|
||||
func (v *SimpleNamedFragmentRandomLeafArticle) GetTypename() string { return v.Typename }
|
||||
|
||||
func (v *SimpleNamedFragmentRandomLeafVideo) implementsGraphQLInterfaceSimpleNamedFragmentRandomLeafLeafContent() {
|
||||
}
|
||||
|
||||
// GetTypename is a part of, and documented with, the interface SimpleNamedFragmentRandomLeafLeafContent.
|
||||
func (v *SimpleNamedFragmentRandomLeafVideo) GetTypename() string { return v.Typename }
|
||||
|
||||
func __unmarshalSimpleNamedFragmentRandomLeafLeafContent(v *SimpleNamedFragmentRandomLeafLeafContent, m json.RawMessage) error {
|
||||
if string(m) == "null" {
|
||||
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(SimpleNamedFragmentRandomLeafArticle)
|
||||
return json.Unmarshal(m, *v)
|
||||
case "Video":
|
||||
*v = new(SimpleNamedFragmentRandomLeafVideo)
|
||||
return json.Unmarshal(m, *v)
|
||||
case "":
|
||||
return fmt.Errorf(
|
||||
"Response was missing LeafContent.__typename")
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
`Unexpected concrete type for SimpleNamedFragmentRandomLeafLeafContent: "%v"`, tn.TypeName)
|
||||
}
|
||||
}
|
||||
|
||||
// SimpleNamedFragmentRandomLeafVideo includes the requested fields of the GraphQL type Video.
|
||||
type SimpleNamedFragmentRandomLeafVideo struct {
|
||||
Typename string `json:"__typename"`
|
||||
VideoFields `json:"-"`
|
||||
}
|
||||
|
||||
func (v *SimpleNamedFragmentRandomLeafVideo) UnmarshalJSON(b []byte) error {
|
||||
|
||||
var firstPass struct {
|
||||
*SimpleNamedFragmentRandomLeafVideo
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.SimpleNamedFragmentRandomLeafVideo = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(b, &v.VideoFields)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SimpleNamedFragmentResponse is returned by SimpleNamedFragment on success.
|
||||
type SimpleNamedFragmentResponse struct {
|
||||
RandomItem SimpleNamedFragmentRandomItemContent `json:"-"`
|
||||
RandomLeaf SimpleNamedFragmentRandomLeafLeafContent `json:"-"`
|
||||
}
|
||||
|
||||
func (v *SimpleNamedFragmentResponse) UnmarshalJSON(b []byte) error {
|
||||
|
||||
var firstPass struct {
|
||||
*SimpleNamedFragmentResponse
|
||||
RandomItem json.RawMessage `json:"randomItem"`
|
||||
RandomLeaf json.RawMessage `json:"randomLeaf"`
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.SimpleNamedFragmentResponse = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.RandomItem
|
||||
raw := firstPass.RandomItem
|
||||
err = __unmarshalSimpleNamedFragmentRandomItemContent(
|
||||
target, raw)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal SimpleNamedFragmentResponse.RandomItem: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
target := &v.RandomLeaf
|
||||
raw := firstPass.RandomLeaf
|
||||
err = __unmarshalSimpleNamedFragmentRandomLeafLeafContent(
|
||||
target, raw)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Unable to unmarshal SimpleNamedFragmentResponse.RandomLeaf: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// VideoFields includes the GraphQL fields of Video requested by the fragment VideoFields.
|
||||
type VideoFields struct {
|
||||
// ID is documented in the Content interface.
|
||||
Id testutil.ID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Url string `json:"url"`
|
||||
Duration int `json:"duration"`
|
||||
Thumbnail VideoFieldsThumbnail `json:"thumbnail"`
|
||||
}
|
||||
|
||||
// VideoFieldsThumbnail includes the requested fields of the GraphQL type Thumbnail.
|
||||
type VideoFieldsThumbnail struct {
|
||||
Id testutil.ID `json:"id"`
|
||||
}
|
||||
|
||||
func SimpleNamedFragment(
|
||||
client graphql.Client,
|
||||
) (*SimpleNamedFragmentResponse, error) {
|
||||
var err error
|
||||
|
||||
var retval SimpleNamedFragmentResponse
|
||||
err = client.MakeRequest(
|
||||
nil,
|
||||
"SimpleNamedFragment",
|
||||
`
|
||||
query SimpleNamedFragment {
|
||||
randomItem {
|
||||
__typename
|
||||
id
|
||||
name
|
||||
... VideoFields
|
||||
}
|
||||
randomLeaf {
|
||||
__typename
|
||||
... VideoFields
|
||||
}
|
||||
}
|
||||
fragment VideoFields on Video {
|
||||
id
|
||||
name
|
||||
url
|
||||
duration
|
||||
thumbnail {
|
||||
id
|
||||
}
|
||||
}
|
||||
`,
|
||||
&retval,
|
||||
nil,
|
||||
)
|
||||
return &retval, err
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"operations": [
|
||||
{
|
||||
"operationName": "SimpleNamedFragment",
|
||||
"query": "\nquery SimpleNamedFragment {\n\trandomItem {\n\t\t__typename\n\t\tid\n\t\tname\n\t\t... VideoFields\n\t}\n\trandomLeaf {\n\t\t__typename\n\t\t... VideoFields\n\t}\n}\nfragment VideoFields on Video {\n\tid\n\tname\n\turl\n\tduration\n\tthumbnail {\n\t\tid\n\t}\n}\n",
|
||||
"sourceLocation": "testdata/queries/SimpleNamedFragment.graphql"
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+4
-4
@@ -82,13 +82,12 @@ type UnionNoFragmentsQueryResponse struct {
|
||||
|
||||
func (v *UnionNoFragmentsQueryResponse) UnmarshalJSON(b []byte) error {
|
||||
|
||||
type UnionNoFragmentsQueryResponseWrapper UnionNoFragmentsQueryResponse
|
||||
|
||||
var firstPass struct {
|
||||
*UnionNoFragmentsQueryResponseWrapper
|
||||
*UnionNoFragmentsQueryResponse
|
||||
RandomLeaf json.RawMessage `json:"randomLeaf"`
|
||||
graphql.NoUnmarshalJSON
|
||||
}
|
||||
firstPass.UnionNoFragmentsQueryResponseWrapper = (*UnionNoFragmentsQueryResponseWrapper)(v)
|
||||
firstPass.UnionNoFragmentsQueryResponse = v
|
||||
|
||||
err := json.Unmarshal(b, &firstPass)
|
||||
if err != nil {
|
||||
@@ -105,6 +104,7 @@ func (v *UnionNoFragmentsQueryResponse) UnmarshalJSON(b []byte) error {
|
||||
"Unable to unmarshal UnionNoFragmentsQueryResponse.RandomLeaf: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user