github.com/opiuman/genqlient@v1.0.0/generate/description.go (about)

     1  package generate
     2  
     3  // Code relating to generating GoDoc from GraphQL descriptions.
     4  //
     5  // For fields, and types where we just copy the "whole" type (enum and
     6  // input-object), this is easy: we just use the GraphQL description.  But for
     7  // struct types, there are often more useful things we can say.
     8  
     9  import (
    10  	"fmt"
    11  	"strings"
    12  )
    13  
    14  // descriptionInfo is embedded in types whose descriptions may be more complex
    15  // than just a copy of the GraphQL doc.
    16  type descriptionInfo struct {
    17  	// user-specified comment for this type
    18  	CommentOverride string
    19  	// name of the corresponding GraphQL type
    20  	GraphQLName string
    21  	// GraphQL schema's description of the type .GraphQLName, if any
    22  	GraphQLDescription string
    23  	// name of the corresponding GraphQL fragment (on .GraphQLName), if any
    24  	FragmentName string
    25  }
    26  
    27  func maybeAddTypeDescription(info descriptionInfo, description string) string {
    28  	if info.GraphQLDescription == "" {
    29  		return description
    30  	}
    31  	return fmt.Sprintf(
    32  		"%v\nThe GraphQL type's documentation follows.\n\n%v",
    33  		description, info.GraphQLDescription)
    34  }
    35  
    36  func fragmentDescription(info descriptionInfo) string {
    37  	return maybeAddTypeDescription(info, fmt.Sprintf(
    38  		"%v includes the GraphQL fields of %v requested by the fragment %v.",
    39  		info.FragmentName, info.GraphQLName, info.FragmentName))
    40  }
    41  
    42  func structDescription(typ *goStructType) string {
    43  	switch {
    44  	case typ.CommentOverride != "":
    45  		return typ.CommentOverride
    46  	case typ.IsInput:
    47  		// Input types have all their fields, just use the GraphQL description.
    48  		return typ.GraphQLDescription
    49  	case typ.FragmentName != "":
    50  		return fragmentDescription(typ.descriptionInfo)
    51  	default:
    52  		// For types where we only have some fields, note that, along with
    53  		// the GraphQL documentation (if any).  We don't want to just use
    54  		// the GraphQL documentation, since it may refer to fields we
    55  		// haven't selected, say.
    56  		return maybeAddTypeDescription(typ.descriptionInfo, fmt.Sprintf(
    57  			"%v includes the requested fields of the GraphQL type %v.",
    58  			typ.GoName, typ.GraphQLName))
    59  	}
    60  }
    61  
    62  func interfaceDescription(typ *goInterfaceType) string {
    63  	goImplNames := make([]string, len(typ.Implementations))
    64  	for i, impl := range typ.Implementations {
    65  		goImplNames[i] = impl.Reference()
    66  	}
    67  	implementationList := fmt.Sprintf(
    68  		"\n\n%v is implemented by the following types:\n\t%v",
    69  		typ.GoName, strings.Join(goImplNames, "\n\t"))
    70  
    71  	switch {
    72  	case typ.CommentOverride != "":
    73  		return typ.CommentOverride + implementationList
    74  	case typ.FragmentName != "":
    75  		return fragmentDescription(typ.descriptionInfo) + implementationList
    76  	default:
    77  		return maybeAddTypeDescription(typ.descriptionInfo, fmt.Sprintf(
    78  			"%v includes the requested fields of the GraphQL interface %v.%v",
    79  			typ.GoName, typ.GraphQLName, implementationList))
    80  	}
    81  }