async-graphql-parser 6.0.10

GraphQL query parser for async-graphql
Documentation
WHITESPACE = _{ " " | "," | "\t" | "\u{feff}" | line_terminator }
COMMENT = _{ "#" ~ (!line_terminator ~ ANY)* }
line_terminator = @{ "\r\n" | "\r" | "\n" }

// Executable //

executable_document   = { SOI ~ executable_definition+ ~ EOI }
executable_definition = { operation_definition | fragment_definition }

operation_definition       = { named_operation_definition | selection_set }
named_operation_definition = { operation_type ~ name? ~ variable_definitions? ~ directives? ~ selection_set }
variable_definitions       = { "(" ~ variable_definition* ~ ")" }
variable_definition        = { variable ~ ":" ~ type_ ~ directives? ~ default_value? }

selection_set = { "{" ~ selection+ ~ "}" }
selection = { field | inline_fragment | fragment_spread }
field = { alias? ~ name ~ arguments? ~ directives? ~ selection_set? }
alias = { name ~ ":" }
fragment_spread = { "..." ~ !type_condition ~ name ~ directives? }
inline_fragment = { "..." ~ type_condition? ~ directives? ~ selection_set }

fragment_definition = { "fragment" ~ name ~ type_condition ~ directives? ~ selection_set }
type_condition = ${ "on" ~ WHITESPACE+ ~ name }

// Service //

service_document       = { SOI ~ type_system_definition+ ~ EOI }
type_system_definition = { schema_definition | type_definition | directive_definition }

schema_definition = {
	"schema" ~ const_directives? ~ "{" ~ operation_type_definition+ ~ "}"
	| extend ~ "schema" ~ (const_directives? ~ "{" ~ operation_type_definition+ ~ "}" | const_directives)
}
operation_type_definition = { operation_type ~ ":" ~ name }

type_definition = { scalar_type | object_type | interface_type | union_type | enum_type | input_object_type }

scalar_type = {
	string? ~ "scalar" ~ name ~ const_directives?
	| extend ~ "scalar" ~ name ~ const_directives
}

object_type = {
	string? ~ "type" ~ name ~ implements_interfaces? ~ const_directives? ~ fields_definition?
	| extend ~ "type" ~ name ~ (implements_interfaces? ~ (const_directives? ~ fields_definition | const_directives) | implements_interfaces)
}
implements_interfaces = { "implements" ~ "&"? ~ name ~ ("&" ~ name)* }

interface_type = {
	string? ~ "interface" ~ name ~ implements_interfaces? ~ const_directives? ~ fields_definition?
	| extend ~ "interface" ~ name ~ implements_interfaces? ~ (const_directives? ~ fields_definition | const_directives)
}

fields_definition = { "{" ~ field_definition+ ~ "}" }
field_definition = { string? ~ name ~ arguments_definition? ~ ":" ~ type_ ~ const_directives? }

union_type = {
	string? ~ "union" ~ name ~ const_directives? ~ union_member_types?
	| extend ~ "union" ~ name ~ (const_directives? ~ union_member_types | const_directives)
}
union_member_types = { "=" ~ "|"? ~ name ~ ("|" ~ name)* }

enum_type = {
	string? ~ "enum" ~ name ~ const_directives? ~ enum_values?
	| extend ~ "enum" ~ name ~ (const_directives? ~ enum_values | const_directives)
}
enum_values = { "{" ~ enum_value_definition+ ~ "}" }
enum_value_definition = { string? ~ enum_value ~ const_directives? }

input_object_type = {
	string? ~ "input" ~ name ~ const_directives? ~ input_fields_definition?
	| extend ~ "input" ~ name ~ (const_directives? ~ input_fields_definition | const_directives)
}
input_fields_definition = { "{" ~ input_value_definition+ ~ "}" }

extend = { "extend" }

directive_definition = { string? ~ "directive" ~ "@" ~ name ~ arguments_definition? ~ repeatable ~ "on" ~ directive_locations }
repeatable = { "repeatable"? }
directive_locations = { "|"? ~ directive_location ~ ("|" ~ directive_location)* }
directive_location = {
	"QUERY"
	| "MUTATION"
	| "SUBSCRIPTION"
	| "FIELD_DEFINITION"
	| "FIELD"
	| "FRAGMENT_DEFINITION"
	| "FRAGMENT_SPREAD"
	| "INLINE_FRAGMENT"
	| "VARIABLE_DEFINITION"
	| "SCHEMA"
	| "SCALAR"
	| "OBJECT"
	| "ARGUMENT_DEFINITION"
	| "INTERFACE"
	| "UNION"
	| "ENUM_VALUE"
	| "ENUM"
	| "INPUT_OBJECT"
	| "INPUT_FIELD_DEFINITION"
}

arguments_definition = { "(" ~ input_value_definition+ ~ ")" }

input_value_definition = { string? ~ name ~ ":" ~ type_ ~ default_value? ~ const_directives? }

// Common //

operation_type = { "query" | "mutation" | "subscription" }

default_value = { "=" ~ const_value }

type_ = @{ (name | "[" ~ type_ ~ "]") ~ "!"? }

const_value = {            number | string | boolean | null | enum_value | const_list | const_object }
value       = { variable | number | string | boolean | null | enum_value |       list |       object }

variable = { "$" ~ name }

number     = @{ (float | int) ~ !name_start }
float      = { int ~ ((fractional ~ exponent) | fractional | exponent) }
fractional = { "." ~ ASCII_DIGIT+ }
exponent   = { ("E" | "e") ~ ("+" | "-")? ~ ASCII_DIGIT+ }
int        = { "-"? ~ ("0" | (ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*)) }

string = ${ ("\"\"\"" ~ block_string_content ~ "\"\"\"") | ("\"" ~ string_content ~ "\"") }
block_string_content = @{ block_string_character* }
block_string_character = {
	(!("\"\"\"" | "\\\"\"\"") ~ ANY)
	| "\\\"\"\""
}
string_content = @{ string_character* }
string_character = {
	(!("\"" | "\\" | line_terminator) ~ ANY)
	| ("\\" ~ ("\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t"))
	| ("\\u" ~ unicode_scalar_value_hex)
}
// Spec inconsistency:
// In GraphQL, strings can contain any Unicode code point. However in Rust strings can only contain
// Unicode Scalar Values. To avoid having to use Vec<u8> everywhere we deviate from the spec
// slightly and disallow non-scalar value code points at the parsing level.
unicode_scalar_value_hex = { !(^"d" ~ ('8'..'9' | 'a'..'f' | 'A'..'F')) ~ ASCII_HEX_DIGIT{4} }

boolean = { "true" | "false" }

null = { "null" }

enum_value = ${ !(boolean | null) ~ name }

const_list = { "[" ~ const_value* ~ "]" }
list       = { "[" ~       value* ~ "]" }

const_object = { "{" ~ const_object_field* ~ "}" }
object       = { "{" ~       object_field* ~ "}" }
const_object_field = { name ~ ":" ~ const_value }
object_field       = { name ~ ":" ~       value }


const_directives = { const_directive+ }
directives       = {       directive+ }
const_directive  = { "@" ~ name ~ const_arguments? }
directive        = { "@" ~ name ~       arguments? }

const_arguments = { "(" ~ const_argument+ ~ ")" }
arguments       = { "(" ~       argument+ ~ ")" }
const_argument = { name ~ ":" ~ const_value }
argument       = { name ~ ":" ~       value }

name_start = @{ (ASCII_ALPHA | "_") }
name = @{ name_start ~ (ASCII_ALPHA | ASCII_DIGIT | "_")* }