use crate::parser::grammar::directive;
use crate::parser::grammar::name;
use crate::parser::grammar::selection;
use crate::parser::grammar::value::Constness;
use crate::parser::grammar::variable;
use crate::Parser;
use crate::SyntaxKind;
use crate::TokenKind;
use crate::T;
pub(crate) fn operation_definition(p: &mut Parser) {
match p.peek() {
Some(TokenKind::Name) => {
let _g = p.start_node(SyntaxKind::OPERATION_DEFINITION);
operation_type(p);
if let Some(TokenKind::Name) = p.peek() {
name::name(p);
}
if let Some(T!['(']) = p.peek() {
variable::variable_definitions(p)
}
if let Some(T![@]) = p.peek() {
directive::directives(p, Constness::NotConst);
}
match p.peek() {
Some(T!['{']) => selection::selection_set(p),
_ => p.err_and_pop("expected a Selection Set"),
}
}
Some(T!['{']) => {
let _g = p.start_node(SyntaxKind::OPERATION_DEFINITION);
selection::selection_set(p)
}
_ => p.err_and_pop("expected an Operation Type or a Selection Set"),
}
}
pub(crate) fn operation_type(p: &mut Parser) {
if let Some(node) = p.peek_data() {
let _g = p.start_node(SyntaxKind::OPERATION_TYPE);
match node {
"query" => p.bump(SyntaxKind::query_KW),
"subscription" => p.bump(SyntaxKind::subscription_KW),
"mutation" => p.bump(SyntaxKind::mutation_KW),
_ => p.err_and_pop("expected either a 'mutation', a 'query', or a 'subscription'"),
}
}
}
#[cfg(test)]
mod test {
use crate::Parser;
#[test]
fn it_continues_parsing_when_operation_definition_starts_with_description() {
let input = "\"description\"{}";
let parser = Parser::new(input);
let cst = parser.parse();
assert_eq!(cst.errors().len(), 2);
assert_eq!(cst.document().definitions().count(), 1);
}
}