diff options
Diffstat (limited to 'vendor/github.com/vektah/gqlgen/neelance/common/literals.go')
-rw-r--r-- | vendor/github.com/vektah/gqlgen/neelance/common/literals.go | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/vendor/github.com/vektah/gqlgen/neelance/common/literals.go b/vendor/github.com/vektah/gqlgen/neelance/common/literals.go new file mode 100644 index 00000000..55619ba0 --- /dev/null +++ b/vendor/github.com/vektah/gqlgen/neelance/common/literals.go @@ -0,0 +1,206 @@ +package common + +import ( + "strconv" + "strings" + "text/scanner" + + "github.com/vektah/gqlgen/neelance/errors" +) + +type Literal interface { + Value(vars map[string]interface{}) interface{} + String() string + Location() errors.Location +} + +type BasicLit struct { + Type rune + Text string + Loc errors.Location +} + +func (lit *BasicLit) Value(vars map[string]interface{}) interface{} { + switch lit.Type { + case scanner.Int: + value, err := strconv.ParseInt(lit.Text, 10, 64) + if err != nil { + panic(err) + } + return int(value) + + case scanner.Float: + value, err := strconv.ParseFloat(lit.Text, 64) + if err != nil { + panic(err) + } + return value + + case scanner.String: + value, err := strconv.Unquote(lit.Text) + if err != nil { + panic(err) + } + return value + + case scanner.Ident: + switch lit.Text { + case "true": + return true + case "false": + return false + default: + return lit.Text + } + + default: + panic("invalid literal") + } +} + +func (lit *BasicLit) String() string { + return lit.Text +} + +func (lit *BasicLit) Location() errors.Location { + return lit.Loc +} + +type ListLit struct { + Entries []Literal + Loc errors.Location +} + +func (lit *ListLit) Value(vars map[string]interface{}) interface{} { + entries := make([]interface{}, len(lit.Entries)) + for i, entry := range lit.Entries { + entries[i] = entry.Value(vars) + } + return entries +} + +func (lit *ListLit) String() string { + entries := make([]string, len(lit.Entries)) + for i, entry := range lit.Entries { + entries[i] = entry.String() + } + return "[" + strings.Join(entries, ", ") + "]" +} + +func (lit *ListLit) Location() errors.Location { + return lit.Loc +} + +type ObjectLit struct { + Fields []*ObjectLitField + Loc errors.Location +} + +type ObjectLitField struct { + Name Ident + Value Literal +} + +func (lit *ObjectLit) Value(vars map[string]interface{}) interface{} { + fields := make(map[string]interface{}, len(lit.Fields)) + for _, f := range lit.Fields { + fields[f.Name.Name] = f.Value.Value(vars) + } + return fields +} + +func (lit *ObjectLit) String() string { + entries := make([]string, 0, len(lit.Fields)) + for _, f := range lit.Fields { + entries = append(entries, f.Name.Name+": "+f.Value.String()) + } + return "{" + strings.Join(entries, ", ") + "}" +} + +func (lit *ObjectLit) Location() errors.Location { + return lit.Loc +} + +type NullLit struct { + Loc errors.Location +} + +func (lit *NullLit) Value(vars map[string]interface{}) interface{} { + return nil +} + +func (lit *NullLit) String() string { + return "null" +} + +func (lit *NullLit) Location() errors.Location { + return lit.Loc +} + +type Variable struct { + Name string + Loc errors.Location +} + +func (v Variable) Value(vars map[string]interface{}) interface{} { + return vars[v.Name] +} + +func (v Variable) String() string { + return "$" + v.Name +} + +func (v *Variable) Location() errors.Location { + return v.Loc +} + +func ParseLiteral(l *Lexer, constOnly bool) Literal { + loc := l.Location() + switch l.Peek() { + case '$': + if constOnly { + l.SyntaxError("variable not allowed") + panic("unreachable") + } + l.ConsumeToken('$') + return &Variable{l.ConsumeIdent(), loc} + + case scanner.Int, scanner.Float, scanner.String, scanner.Ident: + lit := l.ConsumeLiteral() + if lit.Type == scanner.Ident && lit.Text == "null" { + return &NullLit{loc} + } + lit.Loc = loc + return lit + case '-': + l.ConsumeToken('-') + lit := l.ConsumeLiteral() + lit.Text = "-" + lit.Text + lit.Loc = loc + return lit + case '[': + l.ConsumeToken('[') + var list []Literal + for l.Peek() != ']' { + list = append(list, ParseLiteral(l, constOnly)) + } + l.ConsumeToken(']') + return &ListLit{list, loc} + + case '{': + l.ConsumeToken('{') + var fields []*ObjectLitField + for l.Peek() != '}' { + name := l.ConsumeIdentWithLoc() + l.ConsumeToken(':') + value := ParseLiteral(l, constOnly) + fields = append(fields, &ObjectLitField{name, value}) + } + l.ConsumeToken('}') + return &ObjectLit{fields, loc} + + default: + l.SyntaxError("invalid value") + panic("unreachable") + } +} |