github.com/niko0xdev/gqlgen@v0.17.55-0.20240120102243-2ecff98c3e37/codegen/args.go (about) 1 package codegen 2 3 import ( 4 "fmt" 5 "go/types" 6 "strings" 7 8 "github.com/vektah/gqlparser/v2/ast" 9 10 "github.com/niko0xdev/gqlgen/codegen/config" 11 "github.com/niko0xdev/gqlgen/codegen/templates" 12 ) 13 14 type ArgSet struct { 15 Args []*FieldArgument 16 FuncDecl string 17 } 18 19 type FieldArgument struct { 20 *ast.ArgumentDefinition 21 TypeReference *config.TypeReference 22 VarName string // The name of the var in go 23 Object *Object // A link back to the parent object 24 Default interface{} // The default value 25 Directives []*Directive 26 Value interface{} // value set in Data 27 } 28 29 // ImplDirectives get not Builtin and location ARGUMENT_DEFINITION directive 30 func (f *FieldArgument) ImplDirectives() []*Directive { 31 d := make([]*Directive, 0) 32 for i := range f.Directives { 33 if !f.Directives[i].Builtin && f.Directives[i].IsLocation(ast.LocationArgumentDefinition) { 34 d = append(d, f.Directives[i]) 35 } 36 } 37 38 return d 39 } 40 41 func (f *FieldArgument) DirectiveObjName() string { 42 return "rawArgs" 43 } 44 45 func (f *FieldArgument) Stream() bool { 46 return f.Object != nil && f.Object.Stream 47 } 48 49 func (b *builder) buildArg(obj *Object, arg *ast.ArgumentDefinition) (*FieldArgument, error) { 50 tr, err := b.Binder.TypeReference(arg.Type, nil) 51 if err != nil { 52 return nil, err 53 } 54 55 argDirs, err := b.getDirectives(arg.Directives) 56 if err != nil { 57 return nil, err 58 } 59 newArg := FieldArgument{ 60 ArgumentDefinition: arg, 61 TypeReference: tr, 62 Object: obj, 63 VarName: templates.ToGoPrivate(arg.Name), 64 Directives: argDirs, 65 } 66 67 if arg.DefaultValue != nil { 68 newArg.Default, err = arg.DefaultValue.Value(nil) 69 if err != nil { 70 return nil, fmt.Errorf("default value is not valid: %w", err) 71 } 72 } 73 74 return &newArg, nil 75 } 76 77 func (b *builder) bindArgs(field *Field, sig *types.Signature, params *types.Tuple) ([]*FieldArgument, error) { 78 n := params.Len() 79 newArgs := make([]*FieldArgument, 0, len(field.Args)) 80 // Accept variadic methods (i.e. have optional parameters). 81 if params.Len() > len(field.Args) && sig.Variadic() { 82 n = len(field.Args) 83 } 84 nextArg: 85 for j := 0; j < n; j++ { 86 param := params.At(j) 87 for _, oldArg := range field.Args { 88 if strings.EqualFold(oldArg.Name, param.Name()) { 89 tr, err := b.Binder.TypeReference(oldArg.Type, param.Type()) 90 if err != nil { 91 return nil, err 92 } 93 oldArg.TypeReference = tr 94 95 newArgs = append(newArgs, oldArg) 96 continue nextArg 97 } 98 } 99 100 // no matching arg found, abort 101 return nil, fmt.Errorf("arg %s not in schema", param.Name()) 102 } 103 104 return newArgs, nil 105 } 106 107 func (d *Data) Args() map[string][]*FieldArgument { 108 ret := map[string][]*FieldArgument{} 109 for _, o := range d.Objects { 110 for _, f := range o.Fields { 111 if len(f.Args) > 0 { 112 ret[f.ArgsFunc()] = f.Args 113 } 114 } 115 } 116 117 for _, directive := range d.Directives() { 118 if len(directive.Args) > 0 { 119 ret[directive.ArgsFunc()] = directive.Args 120 } 121 } 122 return ret 123 }