Skip to content

Commit

Permalink
proper nil support for lists
Browse files Browse the repository at this point in the history
  • Loading branch information
neelance committed Oct 21, 2016
1 parent 2e3369a commit 20dbb84
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 37 deletions.
24 changes: 12 additions & 12 deletions example/starwars/starwars.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,11 +279,11 @@ func (r *Resolver) Hero(args struct{ Episode string }) characterResolver {
return &droidResolver{droidData["2001"]}
}

func (r *Resolver) Reviews(args struct{ Episode string }) []*reviewResolver {
func (r *Resolver) Reviews(args struct{ Episode string }) *[]*reviewResolver {
panic("TODO")
}

func (r *Resolver) Search(args struct{ Text string }) []searchResultResolver {
func (r *Resolver) Search(args struct{ Text string }) *[]searchResultResolver {
var l []searchResultResolver
for _, h := range humans {
if strings.Contains(h.Name, args.Text) {
Expand All @@ -300,7 +300,7 @@ func (r *Resolver) Search(args struct{ Text string }) []searchResultResolver {
l = append(l, &starshipResolver{s})
}
}
return l
return &l
}

func (r *Resolver) Character(args struct{ ID string }) characterResolver {
Expand Down Expand Up @@ -342,7 +342,7 @@ type friendsConenctionArgs struct {
type characterResolver interface {
ID() string
Name() string
Friends() []characterResolver
Friends() *[]characterResolver
FriendsConnection(friendsConenctionArgs) *friendsConnectionResolver
AppearsIn() []string
ToHuman() (*humanResolver, bool)
Expand All @@ -369,7 +369,7 @@ func (r *humanResolver) Mass() float64 {
return float64(r.h.Mass)
}

func (r *humanResolver) Friends() []characterResolver {
func (r *humanResolver) Friends() *[]characterResolver {
return resolveCharacters(r.h.Friends)
}

Expand All @@ -381,12 +381,12 @@ func (r *humanResolver) AppearsIn() []string {
return r.h.AppearsIn
}

func (r *humanResolver) Starships() []*starshipResolver {
func (r *humanResolver) Starships() *[]*starshipResolver {
l := make([]*starshipResolver, len(r.h.Starships))
for i, id := range r.h.Starships {
l[i] = &starshipResolver{starshipData[id]}
}
return l
return &l
}

func (r *humanResolver) ToHuman() (*humanResolver, bool) {
Expand All @@ -413,7 +413,7 @@ func (r *droidResolver) Name() string {
return r.d.Name
}

func (r *droidResolver) Friends() []characterResolver {
func (r *droidResolver) Friends() *[]characterResolver {
return resolveCharacters(r.d.Friends)
}

Expand Down Expand Up @@ -486,7 +486,7 @@ func convertLength(meters float64, unit string) float64 {
}
}

func resolveCharacters(ids []string) []characterResolver {
func resolveCharacters(ids []string) *[]characterResolver {
var characters []characterResolver
for _, id := range ids {
if h, ok := humanData[id]; ok {
Expand All @@ -496,7 +496,7 @@ func resolveCharacters(ids []string) []characterResolver {
characters = append(characters, &droidResolver{d})
}
}
return characters
return &characters
}

type reviewResolver struct {
Expand All @@ -517,11 +517,11 @@ func (r *friendsConnectionResolver) TotalCount() int {
panic("TODO")
}

func (r *friendsConnectionResolver) Edges() []*friendsEdgeResolver {
func (r *friendsConnectionResolver) Edges() *[]*friendsEdgeResolver {
panic("TODO")
}

func (r *friendsConnectionResolver) Friends() []characterResolver {
func (r *friendsConnectionResolver) Friends() *[]characterResolver {
panic("TODO")
}

Expand Down
36 changes: 18 additions & 18 deletions internal/exec/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func makeExec(target *iExec, s *schema.Schema, t schema.Type, resolverType refle
ref = &typeRef{}
typeRefMap[k] = ref
var err error
ref.exec, err = makeExec2(s, t, resolverType, typeRefMap)
ref.exec, err = makeExec2(s, t, false, resolverType, typeRefMap)
if err != nil {
return err
}
Expand All @@ -75,7 +75,7 @@ func makeExec(target *iExec, s *schema.Schema, t schema.Type, resolverType refle
return nil
}

func makeExec2(s *schema.Schema, t schema.Type, resolverType reflect.Type, typeRefMap map[typeRefMapKey]*typeRef) (iExec, error) {
func makeExec2(s *schema.Schema, t schema.Type, nonNull bool, resolverType reflect.Type, typeRefMap map[typeRefMapKey]*typeRef) (iExec, error) {
switch t := t.(type) {
case *schema.Scalar:
return &scalarExec{}, nil
Expand Down Expand Up @@ -122,21 +122,23 @@ func makeExec2(s *schema.Schema, t schema.Type, resolverType reflect.Type, typeR
return &scalarExec{}, nil

case *schema.List:
if !nonNull {
if resolverType.Kind() != reflect.Ptr {
return nil, fmt.Errorf("%s is not a pointer", resolverType)
}
resolverType = resolverType.Elem()
}
if resolverType.Kind() != reflect.Slice {
return nil, fmt.Errorf("%s is not a slice", resolverType)
}
e := &listExec{}
e := &listExec{nonNull: nonNull}
if err := makeExec(&e.elem, s, t.Elem, resolverType.Elem(), typeRefMap); err != nil {
return nil, err
}
return e, nil

case *schema.NonNull:
e := &nonNilExec{}
if err := makeExec(&e.elem, s, t.Elem, resolverType, typeRefMap); err != nil {
return nil, err
}
return e, nil
return makeExec2(s, t.Elem, true, resolverType, typeRefMap)

default:
panic("invalid type")
Expand Down Expand Up @@ -291,10 +293,17 @@ func (e *scalarExec) exec(r *request, selSet *query.SelectionSet, resolver refle
}

type listExec struct {
elem iExec
elem iExec
nonNull bool
}

func (e *listExec) exec(r *request, selSet *query.SelectionSet, resolver reflect.Value) interface{} {
if !e.nonNull {
if resolver.IsNil() {
return nil
}
resolver = resolver.Elem()
}
l := make([]interface{}, resolver.Len())
var wg sync.WaitGroup
for i := range l {
Expand Down Expand Up @@ -460,15 +469,6 @@ type typeAssertExec struct {
typeExec iExec
}

type nonNilExec struct {
elem iExec
}

func (e *nonNilExec) exec(r *request, selSet *query.SelectionSet, resolver reflect.Value) interface{} {
// TODO ensure non-nil result
return e.elem.exec(r, selSet, resolver)
}

func skipByDirective(r *request, d map[string]*query.Directive) bool {
if skip, ok := d["skip"]; ok {
if execValue(r, skip.Arguments["if"]).(bool) {
Expand Down
14 changes: 7 additions & 7 deletions internal/exec/introspection.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ func (r *typeResolver) Description() string {
return ""
}

func (r *typeResolver) Fields(args struct{ IncludeDeprecated bool }) []*fieldResolver {
func (r *typeResolver) Fields(args struct{ IncludeDeprecated bool }) *[]*fieldResolver {
var fields map[string]*schema.Field
var fieldOrder []string
switch t := r.typ.(type) {
Expand All @@ -239,18 +239,18 @@ func (r *typeResolver) Fields(args struct{ IncludeDeprecated bool }) []*fieldRes
for i, name := range fieldOrder {
l[i] = &fieldResolver{fields[name]}
}
return l
return &l
}

func (r *typeResolver) Interfaces() []*typeResolver {
func (r *typeResolver) Interfaces() *[]*typeResolver {
panic("TODO")
}

func (r *typeResolver) PossibleTypes() []*typeResolver {
func (r *typeResolver) PossibleTypes() *[]*typeResolver {
panic("TODO")
}

func (r *typeResolver) EnumValues(args struct{ IncludeDeprecated bool }) []*enumValueResolver {
func (r *typeResolver) EnumValues(args struct{ IncludeDeprecated bool }) *[]*enumValueResolver {
t, ok := r.typ.(*schema.Enum)
if !ok {
return nil
Expand All @@ -260,10 +260,10 @@ func (r *typeResolver) EnumValues(args struct{ IncludeDeprecated bool }) []*enum
for i, v := range t.Values {
l[i] = &enumValueResolver{v}
}
return l
return &l
}

func (r *typeResolver) InputFields() []*inputValueResolver {
func (r *typeResolver) InputFields() *[]*inputValueResolver {
panic("TODO")
}

Expand Down

0 comments on commit 20dbb84

Please sign in to comment.