From 73759258e589f4ded5977bd6a63a1048ecb7954e Mon Sep 17 00:00:00 2001 From: Richard Musiol Date: Tue, 18 Oct 2016 13:21:49 +0200 Subject: [PATCH] all missing stubs for star wars example --- example/starwars/starwars.go | 161 ++++++++++++++++++++++++++++++++--- internal/exec/exec.go | 15 +++- internal/schema/schema.go | 19 +++-- 3 files changed, 176 insertions(+), 19 deletions(-) diff --git a/example/starwars/starwars.go b/example/starwars/starwars.go index 8c416f1e86f..dc7c9245f6a 100644 --- a/example/starwars/starwars.go +++ b/example/starwars/starwars.go @@ -274,18 +274,55 @@ func (r *Resolver) Hero(args struct{ Episode string }) characterResolver { return &droidResolver{droidData["2001"]} } +func (r *Resolver) Reviews(args struct{ Episode string }) []*reviewResolver { + panic("TODO") +} + +func (r *Resolver) Search(args struct{ Text string }) []characterResolver { + panic("TODO") +} + +func (r *Resolver) Character(args struct{ ID string }) characterResolver { + if h := humanData[args.ID]; h != nil { + return &humanResolver{h} + } + if d := droidData[args.ID]; d != nil { + return &droidResolver{d} + } + return nil +} + func (r *Resolver) Human(args struct{ ID string }) *humanResolver { - h := humanData[args.ID] - if h == nil { - return nil + if h := humanData[args.ID]; h != nil { + return &humanResolver{h} + } + return nil +} + +func (r *Resolver) Droid(args struct{ ID string }) *droidResolver { + if d := droidData[args.ID]; d != nil { + return &droidResolver{d} } - return &humanResolver{h} + return nil +} + +func (r *Resolver) Starship(args struct{ ID string }) *starshipResolver { + if s := starshipData[args.ID]; s != nil { + return &starshipResolver{s} + } + return nil +} + +type friendsConenctionArgs struct { + First int + After string } type characterResolver interface { ID() string Name() string Friends() []characterResolver + FriendsConnection(friendsConenctionArgs) *friendsConnectionResolver AppearsIn() []string } @@ -302,24 +339,33 @@ func (r *humanResolver) Name() string { } func (r *humanResolver) Height(args struct{ Unit string }) float64 { - switch args.Unit { - case "METER": - return r.h.Height - case "FOOT": - return r.h.Height * 3.28084 - default: - panic("invalid unit") - } + return convertLength(r.h.Height, args.Unit) +} + +func (r *humanResolver) Mass() float64 { + return float64(r.h.Mass) } func (r *humanResolver) Friends() []characterResolver { return resolveCharacters(r.h.Friends) } +func (r *humanResolver) FriendsConnection(args friendsConenctionArgs) *friendsConnectionResolver { + panic("TODO") +} + func (r *humanResolver) AppearsIn() []string { return r.h.AppearsIn } +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 +} + type droidResolver struct { d *droid } @@ -336,10 +382,45 @@ func (r *droidResolver) Friends() []characterResolver { return resolveCharacters(r.d.Friends) } +func (r *droidResolver) FriendsConnection(args friendsConenctionArgs) *friendsConnectionResolver { + panic("TODO") +} + func (r *droidResolver) AppearsIn() []string { return r.d.AppearsIn } +func (r *droidResolver) PrimaryFunction() string { + return r.d.PrimaryFunction +} + +type starshipResolver struct { + s *starship +} + +func (r *starshipResolver) ID() string { + return r.s.ID +} + +func (r *starshipResolver) Name() string { + return r.s.Name +} + +func (r *starshipResolver) Length(args struct{ Unit string }) float64 { + return convertLength(r.s.Length, args.Unit) +} + +func convertLength(meters float64, unit string) float64 { + switch unit { + case "METER": + return meters + case "FOOT": + return meters * 3.28084 + default: + panic("invalid unit") + } +} + func resolveCharacters(ids []string) []characterResolver { var characters []characterResolver for _, id := range ids { @@ -352,3 +433,59 @@ func resolveCharacters(ids []string) []characterResolver { } return characters } + +type reviewResolver struct { +} + +func (r *reviewResolver) Stars() int { + panic("TODO") +} + +func (r *reviewResolver) Commentary() string { + panic("TODO") +} + +type friendsConnectionResolver struct { +} + +func (r *friendsConnectionResolver) TotalCount() int { + panic("TODO") +} + +func (r *friendsConnectionResolver) Edges() []*friendsEdgeResolver { + panic("TODO") +} + +func (r *friendsConnectionResolver) Friends() []characterResolver { + panic("TODO") +} + +func (r *friendsConnectionResolver) PageInfo() *pageInfoResolver { + panic("TODO") +} + +type friendsEdgeResolver struct { +} + +func (r *friendsEdgeResolver) Cursor() string { + panic("TODO") +} + +func (r *friendsEdgeResolver) Node() characterResolver { + panic("TODO") +} + +type pageInfoResolver struct { +} + +func (r *pageInfoResolver) StartCursor() string { + panic("TODO") +} + +func (r *pageInfoResolver) EndCursor() string { + panic("TODO") +} + +func (r *pageInfoResolver) HasNextPage() bool { + panic("TODO") +} diff --git a/internal/exec/exec.go b/internal/exec/exec.go index 42e70ed9ceb..fccb8830cf1 100644 --- a/internal/exec/exec.go +++ b/internal/exec/exec.go @@ -1,6 +1,7 @@ package exec import ( + "fmt" "reflect" "strings" "sync" @@ -43,7 +44,8 @@ func makeExec(s *schema.Schema, t schema.Type, resolverType reflect.Type, typeRe } } if methodIndex == -1 { - continue // TODO error + // continue // TODO error + panic(fmt.Errorf("%s does not implement %q: missing method for %q", resolverType, t.Name, name)) // TODO proper error handling } fields[name] = &fieldExec{ @@ -57,16 +59,25 @@ func makeExec(s *schema.Schema, t schema.Type, resolverType reflect.Type, typeRe fields: fields, } + case *schema.Union: + return nil // TODO + case *schema.Enum: return &scalarExec{} case *schema.List: + if resolverType.Kind() != reflect.Slice { + panic(fmt.Errorf("%s is not a slice", resolverType)) // TODO proper error handling + } return &listExec{ elem: makeExec(s, t.Elem, resolverType.Elem(), typeRefMap), } case *schema.TypeReference: - refT := s.Types[t.Name] + refT, ok := s.Types[t.Name] + if !ok { + panic("type not found: " + t.Name) // TODO proper error + } k := typeRefMapKey{refT, resolverType} e, ok := typeRefMap[k] if !ok { diff --git a/internal/schema/schema.go b/internal/schema/schema.go index 89462214916..6771e287844 100644 --- a/internal/schema/schema.go +++ b/internal/schema/schema.go @@ -25,6 +25,11 @@ type Object struct { Fields map[string]*Field } +type Union struct { + Name string + Types []string +} + type Enum struct { Name string Values []string @@ -40,6 +45,7 @@ type TypeReference struct { func (Scalar) isType() {} func (Object) isType() {} +func (Union) isType() {} func (Enum) isType() {} func (List) isType() {} func (TypeReference) isType() {} @@ -100,7 +106,8 @@ func parseSchema(l *lexer.Lexer) *Schema { obj := parseTypeDecl(l) // TODO s.Types[obj.Name] = obj case "union": - parseUnionDecl(l) // TODO + union := parseUnionDecl(l) + s.Types[union.Name] = union case "enum": enum := parseEnumDecl(l) s.Types[enum.Name] = enum @@ -146,14 +153,16 @@ func parseEnumDecl(l *lexer.Lexer) *Enum { return enum } -func parseUnionDecl(l *lexer.Lexer) { - l.ConsumeIdent() +func parseUnionDecl(l *lexer.Lexer) *Union { + union := &Union{} + union.Name = l.ConsumeIdent() l.ConsumeToken('=') - l.ConsumeIdent() + union.Types = []string{l.ConsumeIdent()} for l.Peek() == '|' { l.ConsumeToken('|') - l.ConsumeIdent() + union.Types = append(union.Types, l.ConsumeIdent()) } + return union } func parseInputDecl(l *lexer.Lexer) {