apollo_parser/parser/grammar/
operation.rs1use crate::parser::grammar::directive;
2use crate::parser::grammar::name;
3use crate::parser::grammar::selection;
4use crate::parser::grammar::value::Constness;
5use crate::parser::grammar::variable;
6use crate::Parser;
7use crate::SyntaxKind;
8use crate::TokenKind;
9use crate::T;
10
11pub(crate) fn operation_definition(p: &mut Parser) {
17 match p.peek() {
18 Some(TokenKind::Name) => {
19 let _g = p.start_node(SyntaxKind::OPERATION_DEFINITION);
20
21 operation_type(p);
22
23 if let Some(TokenKind::Name) = p.peek() {
24 name::name(p);
25 }
26
27 if let Some(T!['(']) = p.peek() {
28 variable::variable_definitions(p)
29 }
30
31 if let Some(T![@]) = p.peek() {
32 directive::directives(p, Constness::NotConst);
33 }
34
35 match p.peek() {
36 Some(T!['{']) => selection::selection_set(p),
37 _ => p.err_and_pop("expected a Selection Set"),
38 }
39 }
40 Some(T!['{']) => {
41 let _g = p.start_node(SyntaxKind::OPERATION_DEFINITION);
42
43 selection::selection_set(p)
44 }
45 _ => p.err_and_pop("expected an Operation Type or a Selection Set"),
46 }
47}
48
49pub(crate) fn operation_type(p: &mut Parser) {
54 if let Some(node) = p.peek_data() {
55 let _g = p.start_node(SyntaxKind::OPERATION_TYPE);
56 match node {
57 "query" => p.bump(SyntaxKind::query_KW),
58 "subscription" => p.bump(SyntaxKind::subscription_KW),
59 "mutation" => p.bump(SyntaxKind::mutation_KW),
60 _ => p.err_and_pop("expected either a 'mutation', a 'query', or a 'subscription'"),
61 }
62 }
63}
64
65#[cfg(test)]
66mod test {
67 use crate::Parser;
68
69 #[test]
72 fn it_continues_parsing_when_operation_definition_starts_with_description() {
73 let input = "\"description\"{}";
74 let parser = Parser::new(input);
75 let cst = parser.parse();
76
77 assert_eq!(cst.errors().len(), 2);
78 assert_eq!(cst.document().definitions().count(), 1);
79 }
80}