1use super::ast::*;
2use super::ast_kind::ASTKind;
3use super::lexer::{Extras, Token};
4use crate::error::{get_location, print_span, Error, ErrorType, Result};
5use bumpalo::collections::Vec;
6use logos::{Lexer, Logos, Span};
7
8type ParseResult<T> = std::result::Result<T, ASTKind>;
9
10pub(crate) mod private {
11 use super::{ASTContext, Extras, Lexer, Logos, ParseResult, Span, Token};
12
13 pub struct ParserContext<'a> {
16 pub(crate) arena: &'a bumpalo::Bump,
17 pub(crate) peek: Option<Token<'a>>,
18 pub(crate) iter: Lexer<'a, Token<'a>>,
19 pub(crate) in_var_def: bool,
20 }
21
22 impl<'a> ParserContext<'a> {
23 pub(crate) fn new(ctx: &'a ASTContext, source: &'a str) -> Self {
26 let extras = Extras { arena: &ctx.arena };
27 ParserContext {
28 arena: &ctx.arena,
29 peek: None,
30 iter: Token::lexer_with_extras(source, extras),
31 in_var_def: false,
32 }
33 }
34
35 #[inline]
36 pub(crate) fn next(&mut self) -> Token<'a> {
37 match self.peek.take() {
38 Some(token) => token,
39 None => self.iter.next().unwrap_or(Token::End),
40 }
41 }
42
43 #[inline]
44 pub(crate) fn peek(&mut self) -> &Token<'a> {
45 let iter = &mut self.iter;
46 self.peek
47 .get_or_insert_with(|| iter.next().unwrap_or(Token::End))
48 }
49
50 #[inline]
51 pub(crate) fn source(&self) -> &str {
52 self.iter.source()
53 }
54
55 #[inline]
56 pub(crate) fn span(&self) -> Span {
57 self.iter.span()
58 }
59 }
60
61 pub trait ParseNode<'a>: Sized {
64 fn new_with_ctx(ctx: &mut ParserContext<'a>) -> ParseResult<Self>;
65 }
66}
67
68pub trait ParseNode<'a>: private::ParseNode<'a> {
73 fn parse<T: ToString>(ctx: &'a ASTContext, source: T) -> Result<&'a Self> {
76 let source = ctx.alloc_string(source.to_string());
77 let mut parser_ctx = private::ParserContext::new(ctx, source);
78 match Self::new_with_ctx(&mut parser_ctx) {
79 Ok(value) => Ok(ctx.alloc(value)),
80 Err(error) => {
81 let span = print_span(parser_ctx.source(), parser_ctx.span());
82 let location = get_location(parser_ctx.source(), parser_ctx.span());
83 let message = format!("Invalid {}", error);
84 Err(Error::new_with_context(
85 message,
86 Some(location),
87 span,
88 Some(ErrorType::Syntax),
89 ))
90 }
91 }
92 }
93}
94
95impl<'a, T: private::ParseNode<'a>> ParseNode<'a> for T {}
96
97impl<'a> private::ParseNode<'a> for BooleanValue {
98 #[inline]
99 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<BooleanValue> {
100 match ctx.next() {
101 Token::Name("true") => Ok(BooleanValue { value: true }),
102 Token::Name("false") => Ok(BooleanValue { value: false }),
103 _ => Err(ASTKind::Boolean),
104 }
105 }
106}
107
108impl<'a> private::ParseNode<'a> for EnumValue<'a> {
109 #[inline]
110 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<EnumValue<'a>> {
111 match ctx.next() {
112 Token::Name("true" | "false" | "null") => Err(ASTKind::Enum),
113 Token::Name(value) => Ok(EnumValue { value }),
114 _ => Err(ASTKind::Enum),
115 }
116 }
117}
118
119impl<'a> private::ParseNode<'a> for FloatValue<'a> {
120 #[inline]
121 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<FloatValue<'a>> {
122 if let Token::Float(value) = ctx.next() {
123 Ok(FloatValue { value })
124 } else {
125 Err(ASTKind::Float)
126 }
127 }
128}
129
130impl<'a> private::ParseNode<'a> for IntValue<'a> {
131 #[inline]
132 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<IntValue<'a>> {
133 if let Token::Integer(value) = ctx.next() {
134 Ok(IntValue { value })
135 } else {
136 Err(ASTKind::Int)
137 }
138 }
139}
140
141impl<'a> private::ParseNode<'a> for StringValue<'a> {
142 #[inline]
143 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<StringValue<'a>> {
144 if let Token::String(value) = ctx.next() {
145 Ok(StringValue { value })
146 } else {
147 Err(ASTKind::String)
148 }
149 }
150}
151
152impl<'a> private::ParseNode<'a> for Variable<'a> {
153 #[inline]
154 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<Variable<'a>> {
155 if let Token::VariableName(name) = ctx.next() {
156 Ok(Variable { name })
157 } else {
158 Err(ASTKind::Variable)
159 }
160 }
161}
162
163impl<'a> private::ParseNode<'a> for Value<'a> {
164 #[inline]
165 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<Value<'a>> {
166 let in_var_def = ctx.in_var_def;
167 match ctx.peek() {
168 Token::Name("null") => {
169 ctx.next();
170 Ok(Value::Null)
171 }
172 Token::VariableName(_) if in_var_def => Err(ASTKind::VariableDefinition),
173 Token::VariableName(_) => Variable::new_with_ctx(ctx).map(Value::Variable),
174 Token::Name("true" | "false") => BooleanValue::new_with_ctx(ctx).map(Value::Boolean),
175 Token::Name(_) => EnumValue::new_with_ctx(ctx).map(Value::Enum),
176 Token::Float(_) => FloatValue::new_with_ctx(ctx).map(Value::Float),
177 Token::Integer(_) => IntValue::new_with_ctx(ctx).map(Value::Int),
178 Token::String(_) => StringValue::new_with_ctx(ctx).map(Value::String),
179 Token::BracketOpen => ListValue::new_with_ctx(ctx).map(Value::List),
180 Token::BraceOpen => ObjectValue::new_with_ctx(ctx).map(Value::Object),
181 _ => Err(ASTKind::Value),
182 }
183 }
184}
185
186impl<'a> private::ParseNode<'a> for ObjectField<'a> {
187 #[inline]
188 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<ObjectField<'a>> {
189 if let Token::Name(name) = ctx.next() {
190 if let Token::Colon = ctx.next() {
191 let value = Value::new_with_ctx(ctx)?;
192 return Ok(ObjectField { name, value });
193 }
194 }
195 Err(ASTKind::ObjectField)
196 }
197}
198
199impl<'a> private::ParseNode<'a> for ObjectValue<'a> {
200 #[inline]
201 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<ObjectValue<'a>> {
202 if let Token::BraceOpen = ctx.next() {
203 let children = if let Token::BraceClose = ctx.peek() {
204 ctx.next();
205 Vec::new_in(ctx.arena)
206 } else {
207 let mut builder = Vec::new_in(ctx.arena);
208 loop {
209 builder.push(ObjectField::new_with_ctx(ctx)?);
210 if let Token::BraceClose = ctx.peek() {
211 ctx.next();
212 break;
213 }
214 }
215 builder
216 };
217 Ok(ObjectValue { children })
218 } else {
219 Err(ASTKind::Object)
220 }
221 }
222}
223
224impl<'a> private::ParseNode<'a> for ListValue<'a> {
225 #[inline]
226 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<ListValue<'a>> {
227 if let Token::BracketOpen = ctx.next() {
228 let children = if let Token::BracketClose = ctx.peek() {
229 ctx.next();
230 Vec::new_in(ctx.arena)
231 } else {
232 let mut builder = Vec::new_in(ctx.arena);
233 loop {
234 builder.push(Value::new_with_ctx(ctx)?);
235 if let Token::BracketClose = ctx.peek() {
236 ctx.next();
237 break;
238 }
239 }
240 builder
241 };
242 Ok(ListValue { children })
243 } else {
244 Err(ASTKind::List)
245 }
246 }
247}
248
249impl<'a> private::ParseNode<'a> for Argument<'a> {
250 #[inline]
251 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<Argument<'a>> {
252 if let Token::Name(name) = ctx.next() {
253 if let Token::Colon = ctx.next() {
254 let value = Value::new_with_ctx(ctx)?;
255 return Ok(Argument { name, value });
256 }
257 }
258 Err(ASTKind::Argument)
259 }
260}
261
262impl<'a> private::ParseNode<'a> for Arguments<'a> {
263 #[inline]
264 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<Arguments<'a>> {
265 let children = if let Token::ParenOpen = ctx.peek() {
266 ctx.next();
267 if let Token::ParenClose = ctx.peek() {
268 ctx.next();
269 Vec::new_in(ctx.arena)
270 } else {
271 let mut builder = Vec::new_in(ctx.arena);
272 loop {
273 builder.push(Argument::new_with_ctx(ctx)?);
274 if let Token::ParenClose = ctx.peek() {
275 ctx.next();
276 break;
277 }
278 }
279 builder
280 }
281 } else {
282 Vec::new_in(ctx.arena)
283 };
284 Ok(Arguments { children })
285 }
286}
287
288impl<'a> private::ParseNode<'a> for Directive<'a> {
289 #[inline]
290 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<Directive<'a>> {
291 if let Token::DirectiveName(name) = ctx.next() {
292 let arguments = Arguments::new_with_ctx(ctx)?;
293 Ok(Directive { name, arguments })
294 } else {
295 Err(ASTKind::Directive)
296 }
297 }
298}
299
300impl<'a> private::ParseNode<'a> for Directives<'a> {
301 #[inline]
302 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<Directives<'a>> {
303 let mut builder = Vec::new_in(ctx.arena);
304 while let Token::DirectiveName(_) = ctx.peek() {
305 builder.push(Directive::new_with_ctx(ctx)?);
306 }
307 Ok(Directives { children: builder })
308 }
309}
310
311impl<'a> private::ParseNode<'a> for Field<'a> {
312 #[inline]
313 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<Field<'a>> {
314 if let Token::Name(name_or_alias) = ctx.next() {
315 let (alias, name) = if let Token::Colon = ctx.peek() {
316 ctx.next();
317 if let Token::Name(name) = ctx.next() {
318 (Some(name_or_alias), name)
319 } else {
320 return Err(ASTKind::Field);
321 }
322 } else {
323 (None, name_or_alias)
324 };
325
326 let arguments = Arguments::new_with_ctx(ctx)?;
327 let directives = Directives::new_with_ctx(ctx)?;
328 let selection_set = SelectionSet::new_with_ctx(ctx)?;
329
330 Ok(Field {
331 alias,
332 name,
333 arguments,
334 directives,
335 selection_set,
336 })
337 } else {
338 Err(ASTKind::Field)
339 }
340 }
341}
342
343impl<'a> private::ParseNode<'a> for FragmentSpread<'a> {
344 #[inline]
345 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<FragmentSpread<'a>> {
346 if let Token::Ellipsis = ctx.peek() {
347 ctx.next();
348 };
349 match ctx.peek() {
350 Token::Name("on") => Err(ASTKind::FragmentSpread),
351 Token::Name(_) => {
352 let name = NamedType::new_with_ctx(ctx)?;
353 let directives = Directives::new_with_ctx(ctx)?;
354 Ok(FragmentSpread { name, directives })
355 }
356 _ => Err(ASTKind::FragmentSpread),
357 }
358 }
359}
360
361impl<'a> private::ParseNode<'a> for NamedType<'a> {
362 #[inline]
363 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<NamedType<'a>> {
364 if let Token::Name(name) = ctx.next() {
365 Ok(NamedType { name })
366 } else {
367 Err(ASTKind::NamedType)
368 }
369 }
370}
371
372impl<'a> private::ParseNode<'a> for InlineFragment<'a> {
373 #[inline]
374 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<InlineFragment<'a>> {
375 if let Token::Ellipsis = ctx.peek() {
376 ctx.next();
377 };
378 let type_condition = if let Token::Name("on") = ctx.peek() {
379 ctx.next();
380 Some(NamedType::new_with_ctx(ctx)?)
381 } else {
382 None
383 };
384 let directives = Directives::new_with_ctx(ctx)?;
385 if let Token::BraceOpen = ctx.peek() {
386 let selection_set = SelectionSet::new_with_ctx(ctx)?;
387 Ok(InlineFragment {
388 type_condition,
389 directives,
390 selection_set,
391 })
392 } else {
393 Err(ASTKind::InlineFragment)
394 }
395 }
396}
397
398impl<'a> private::ParseNode<'a> for Selection<'a> {
399 #[inline]
400 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<Selection<'a>> {
401 match ctx.peek() {
402 Token::Name(_) => Field::new_with_ctx(ctx).map(Selection::Field),
403 Token::Ellipsis => {
404 ctx.next();
405 match ctx.peek() {
406 Token::DirectiveName(_) | Token::BraceOpen | Token::Name("on") => {
407 InlineFragment::new_with_ctx(ctx).map(Selection::InlineFragment)
408 }
409 Token::Name(_) => {
410 FragmentSpread::new_with_ctx(ctx).map(Selection::FragmentSpread)
411 }
412 _ => Err(ASTKind::Selection),
413 }
414 }
415 _ => Err(ASTKind::Selection),
416 }
417 }
418}
419
420impl<'a> private::ParseNode<'a> for SelectionSet<'a> {
421 #[inline]
422 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<SelectionSet<'a>> {
423 let selections = if let Token::BraceOpen = ctx.peek() {
424 ctx.next();
425 let mut builder = Vec::new_in(ctx.arena);
426 loop {
427 builder.push(Selection::new_with_ctx(ctx)?);
428 if let Token::BraceClose = ctx.peek() {
429 ctx.next();
430 break;
431 }
432 }
433 builder
434 } else {
435 Vec::new_in(ctx.arena)
436 };
437 Ok(SelectionSet { selections })
438 }
439}
440
441impl<'a> private::ParseNode<'a> for Type<'a> {
442 #[inline]
443 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<Type<'a>> {
444 let token = ctx.next();
445 let of_type = if let Token::BracketOpen = token {
446 let inner = Type::new_with_ctx(ctx)?;
447 if let Token::BracketClose = ctx.next() {
448 Type::ListType(ctx.arena.alloc(inner))
449 } else {
450 return Err(ASTKind::ListType);
451 }
452 } else if let Token::Name(name) = token {
453 Type::NamedType(NamedType { name })
454 } else {
455 return Err(ASTKind::Type);
456 };
457 if let Token::Exclam = ctx.peek() {
458 ctx.next();
459 Ok(Type::NonNullType(ctx.arena.alloc(of_type)))
460 } else {
461 Ok(of_type)
462 }
463 }
464}
465
466impl<'a> private::ParseNode<'a> for VariableDefinition<'a> {
467 #[inline]
468 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<VariableDefinition<'a>> {
469 let variable = Variable::new_with_ctx(ctx)?;
470 let of_type = if let Token::Colon = ctx.next() {
471 Type::new_with_ctx(ctx)?
472 } else {
473 return Err(ASTKind::VariableDefinition);
474 };
475 let default_value = if let Token::Equal = ctx.peek() {
476 ctx.next();
477 ctx.in_var_def = true;
478 let value = Value::new_with_ctx(ctx)?;
479 ctx.in_var_def = false;
480 value
481 } else {
482 Value::Null
483 };
484 let directives = Directives::new_with_ctx(ctx)?;
485 Ok(VariableDefinition {
486 variable,
487 of_type,
488 default_value,
489 directives,
490 })
491 }
492}
493
494impl<'a> private::ParseNode<'a> for VariableDefinitions<'a> {
495 #[inline]
496 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<VariableDefinitions<'a>> {
497 let children = if let Token::ParenOpen = ctx.peek() {
498 ctx.next();
499 let mut builder = Vec::new_in(ctx.arena);
500 loop {
501 builder.push(VariableDefinition::new_with_ctx(ctx)?);
502 if let Token::ParenClose = ctx.peek() {
503 ctx.next();
504 break;
505 }
506 }
507 builder
508 } else {
509 Vec::new_in(ctx.arena)
510 };
511 Ok(VariableDefinitions { children })
512 }
513}
514
515impl<'a> private::ParseNode<'a> for FragmentDefinition<'a> {
516 #[inline]
517 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<FragmentDefinition<'a>> {
518 if let Token::Name("fragment") = ctx.next() {
519 let name = NamedType::new_with_ctx(ctx)?;
520 let type_condition = if let Token::Name("on") = ctx.next() {
521 NamedType::new_with_ctx(ctx)?
522 } else {
523 return Err(ASTKind::FragmentDefinition);
524 };
525 let directives = Directives::new_with_ctx(ctx)?;
526 let selection_set = if let Token::BraceOpen = ctx.peek() {
527 SelectionSet::new_with_ctx(ctx)?
528 } else {
529 return Err(ASTKind::FragmentDefinition);
530 };
531 Ok(FragmentDefinition {
532 name,
533 type_condition,
534 directives,
535 selection_set,
536 })
537 } else {
538 Err(ASTKind::FragmentDefinition)
539 }
540 }
541}
542
543impl<'a> private::ParseNode<'a> for OperationKind {
544 #[inline]
545 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<OperationKind> {
546 match ctx.next() {
547 Token::Name("query") => Ok(OperationKind::Query),
548 Token::Name("mutation") => Ok(OperationKind::Mutation),
549 Token::Name("subscription") => Ok(OperationKind::Subscription),
550 _ => Err(ASTKind::OperationKind),
551 }
552 }
553}
554
555impl<'a> private::ParseNode<'a> for OperationDefinition<'a> {
556 #[inline]
557 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<OperationDefinition<'a>> {
558 let operation = match ctx.peek() {
559 Token::BraceOpen => {
560 let selection_set = SelectionSet::new_with_ctx(ctx)?;
561 return Ok(OperationDefinition {
562 operation: OperationKind::Query,
563 name: None,
564 variable_definitions: VariableDefinitions::default_in(ctx.arena),
565 directives: Directives::default_in(ctx.arena),
566 selection_set,
567 });
568 }
569 Token::Name("query") => OperationKind::Query,
570 Token::Name("mutation") => OperationKind::Mutation,
571 Token::Name("subscription") => OperationKind::Subscription,
572 _ => return Err(ASTKind::OperationDefinition),
573 };
574 ctx.next();
575 let name = if let Token::Name(_) = ctx.peek() {
576 NamedType::new_with_ctx(ctx).ok()
577 } else {
578 None
579 };
580 let variable_definitions = VariableDefinitions::new_with_ctx(ctx)?;
581 let directives = Directives::new_with_ctx(ctx)?;
582 if let Token::BraceOpen = ctx.peek() {
583 let selection_set = SelectionSet::new_with_ctx(ctx)?;
584 Ok(OperationDefinition {
585 operation,
586 name,
587 variable_definitions,
588 directives,
589 selection_set,
590 })
591 } else {
592 Err(ASTKind::OperationDefinition)
593 }
594 }
595}
596
597impl<'a> private::ParseNode<'a> for Document<'a> {
598 #[inline]
599 fn new_with_ctx(ctx: &mut private::ParserContext<'a>) -> ParseResult<Document<'a>> {
600 let mut definitions = Vec::new_in(ctx.arena);
601 loop {
602 let definition = match ctx.peek() {
603 Token::BraceOpen | Token::Name("query" | "mutation" | "subscription") => {
604 OperationDefinition::new_with_ctx(ctx).map(Definition::Operation)
605 }
606 Token::Name("fragment") => {
607 FragmentDefinition::new_with_ctx(ctx).map(Definition::Fragment)
608 }
609 Token::End => break,
610 _ => Err(ASTKind::Document),
611 }?;
612 definitions.push(definition);
613 }
614 Ok(Document {
615 definitions,
616 size_hint: ctx.iter.span().end,
617 })
618 }
619}
620
621#[cfg(test)]
622mod tests {
623 use bumpalo::collections::Vec;
624
625 use crate::error::Location;
626
627 use super::{super::ast::*, ParseNode};
628
629 fn assert_parse<'a, T: 'a>(ctx: &'a ASTContext, source: &'a str, expected: T)
630 where
631 T: ParseNode<'a> + std::fmt::Debug + PartialEq,
632 {
633 assert_eq!(*T::parse(ctx, source).unwrap(), expected);
634 }
635
636 #[test]
637 fn error() {
638 let ctx = ASTContext::new();
639 let result = Document::parse(&ctx, "query { document { $ }}");
640
641 assert_eq!(
642 result.err().unwrap().location,
643 Some(Location {
644 column: 19,
645 line: 1
646 })
647 );
648
649 let result = Document::parse(
650 &ctx,
651 "query {
652 document {
653 $
654 }
655 }",
656 );
657 assert_eq!(
658 result.err().unwrap().location,
659 Some(Location {
660 column: 16,
661 line: 3
662 })
663 );
664 }
665
666 #[test]
667 fn named_type() {
668 let ctx = ASTContext::new();
669 assert_parse(&ctx, "TypeName", NamedType { name: "TypeName" });
670 }
671
672 #[test]
673 fn variable() {
674 let ctx = ASTContext::new();
675 assert_parse(&ctx, "$test", Variable { name: "test" });
676 }
677
678 #[test]
679 fn lists() {
680 let ctx = ASTContext::new();
681 assert_parse(
682 &ctx,
683 "[]",
684 ListValue {
685 children: Vec::new_in(&ctx.arena),
686 },
687 );
688
689 let list_children = Vec::from_iter_in([Value::Null, Value::Null], &ctx.arena);
690 assert_parse(
691 &ctx,
692 "[null, null]",
693 ListValue {
694 children: list_children,
695 },
696 );
697 }
698
699 #[test]
700 fn objects() {
701 let ctx = ASTContext::new();
702 assert_parse(
703 &ctx,
704 "{}",
705 ObjectValue {
706 children: Vec::new_in(&ctx.arena),
707 },
708 );
709 let list_children = Vec::from_iter_in(
710 [ObjectField {
711 name: "test",
712 value: Value::Boolean(BooleanValue { value: true }),
713 }],
714 &ctx.arena,
715 );
716 assert_parse(
717 &ctx,
718 "{ test: true }",
719 ObjectValue {
720 children: list_children,
721 },
722 );
723 }
724
725 #[test]
726 fn values() {
727 let ctx = ASTContext::new();
728 assert_parse(&ctx, "true", Value::Boolean(BooleanValue { value: true }));
729 assert_parse(&ctx, "false", Value::Boolean(BooleanValue { value: false }));
730 assert_parse(&ctx, "$var", Value::Variable(Variable { name: "var" }));
731 assert_parse(&ctx, "Opt", Value::Enum(EnumValue { value: "Opt" }));
732 assert_parse(&ctx, "123", Value::Int(IntValue { value: "123" }));
733 assert_parse(&ctx, "0.0", Value::Float(FloatValue { value: "0.0" }));
734 assert_parse(&ctx, "null", Value::Null);
735
736 assert_parse(
737 &ctx,
738 "\"hello world\"",
739 Value::String(StringValue::new(&ctx, "hello world")),
740 );
741
742 assert_parse(
743 &ctx,
744 "[]",
745 Value::List(ListValue {
746 children: Vec::new_in(&ctx.arena),
747 }),
748 );
749 assert_parse(
750 &ctx,
751 "[null, null]",
752 Value::List(ListValue {
753 children: Vec::from_iter_in([Value::Null, Value::Null], &ctx.arena),
754 }),
755 );
756
757 assert_parse(
758 &ctx,
759 "{}",
760 Value::Object(ObjectValue {
761 children: Vec::new_in(&ctx.arena),
762 }),
763 );
764 assert_parse(
765 &ctx,
766 "{ test: true }",
767 Value::Object(ObjectValue {
768 children: Vec::from_iter_in(
769 [ObjectField {
770 name: "test",
771 value: Value::Boolean(BooleanValue { value: true }),
772 }],
773 &ctx.arena,
774 ),
775 }),
776 );
777 }
778
779 #[test]
780 fn arguments() {
781 let ctx = ASTContext::new();
782 assert_parse(
783 &ctx,
784 "()",
785 Arguments {
786 children: Vec::new_in(&ctx.arena),
787 },
788 );
789 assert_parse(
790 &ctx,
791 "(a: 1, b: 2)",
792 Arguments {
793 children: Vec::from_iter_in(
794 [
795 Argument {
796 name: "a",
797 value: Value::Int(IntValue { value: "1" }),
798 },
799 Argument {
800 name: "b",
801 value: Value::Int(IntValue { value: "2" }),
802 },
803 ],
804 &ctx.arena,
805 ),
806 },
807 );
808 }
809
810 #[test]
811 fn directives() {
812 let ctx = ASTContext::new();
813
814 assert_parse(
815 &ctx,
816 "#",
817 Directives {
818 children: Vec::new_in(&ctx.arena),
819 },
820 );
821
822 assert_parse(
823 &ctx,
824 "@defer",
825 Directives {
826 children: Vec::from_iter_in(
827 [Directive {
828 name: "defer",
829 arguments: Arguments {
830 children: Vec::new_in(&ctx.arena),
831 },
832 }],
833 &ctx.arena,
834 ),
835 },
836 );
837
838 assert_parse(
839 &ctx,
840 "@defer @defer",
841 Directives {
842 children: Vec::from_iter_in(
843 [
844 Directive {
845 name: "defer",
846 arguments: Arguments {
847 children: Vec::new_in(&ctx.arena),
848 },
849 },
850 Directive {
851 name: "defer",
852 arguments: Arguments {
853 children: Vec::new_in(&ctx.arena),
854 },
855 },
856 ],
857 &ctx.arena,
858 ),
859 },
860 );
861
862 assert_parse(
863 &ctx,
864 "@include(if: $hi)",
865 Directive {
866 name: "include",
867 arguments: Arguments {
868 children: Vec::from_iter_in(
869 [Argument {
870 name: "if",
871 value: Value::Variable(Variable { name: "hi" }),
872 }],
873 &ctx.arena,
874 ),
875 },
876 },
877 );
878 }
879
880 #[test]
881 fn fields() {
882 let ctx = ASTContext::new();
883
884 assert_parse(
885 &ctx,
886 "name",
887 Field {
888 alias: None,
889 name: "name",
890 arguments: Arguments {
891 children: Vec::new_in(&ctx.arena),
892 },
893 directives: Directives {
894 children: Vec::new_in(&ctx.arena),
895 },
896 selection_set: SelectionSet {
897 selections: Vec::new_in(&ctx.arena),
898 },
899 },
900 );
901
902 assert_parse(
903 &ctx,
904 "name: name",
905 Field {
906 alias: Some("name"),
907 name: "name",
908 arguments: Arguments {
909 children: Vec::new_in(&ctx.arena),
910 },
911 directives: Directives {
912 children: Vec::new_in(&ctx.arena),
913 },
914 selection_set: SelectionSet {
915 selections: Vec::new_in(&ctx.arena),
916 },
917 },
918 );
919
920 assert_parse(
921 &ctx,
922 "alias: name",
923 Field {
924 alias: Some("alias"),
925 name: "name",
926 arguments: Arguments {
927 children: Vec::new_in(&ctx.arena),
928 },
929 directives: Directives {
930 children: Vec::new_in(&ctx.arena),
931 },
932 selection_set: SelectionSet {
933 selections: Vec::new_in(&ctx.arena),
934 },
935 },
936 );
937
938 assert_parse(
939 &ctx,
940 "alias: name(x: null)",
941 Field {
942 alias: Some("alias"),
943 name: "name",
944 arguments: Arguments {
945 children: Vec::from_iter_in(
946 [Argument {
947 name: "x",
948 value: Value::Null,
949 }],
950 &ctx.arena,
951 ),
952 },
953 directives: Directives {
954 children: Vec::new_in(&ctx.arena),
955 },
956 selection_set: SelectionSet {
957 selections: Vec::new_in(&ctx.arena),
958 },
959 },
960 );
961
962 assert_parse(
963 &ctx,
964 "alias: name(x: null) @skip(if: true)",
965 Field {
966 alias: Some("alias"),
967 name: "name",
968 arguments: Arguments {
969 children: Vec::from_iter_in(
970 [Argument {
971 name: "x",
972 value: Value::Null,
973 }],
974 &ctx.arena,
975 ),
976 },
977 directives: Directives {
978 children: Vec::from_iter_in(
979 [Directive {
980 name: "skip",
981 arguments: Arguments {
982 children: Vec::from_iter_in(
983 [Argument {
984 name: "if",
985 value: Value::Boolean(BooleanValue { value: true }),
986 }],
987 &ctx.arena,
988 ),
989 },
990 }],
991 &ctx.arena,
992 ),
993 },
994 selection_set: SelectionSet {
995 selections: Vec::new_in(&ctx.arena),
996 },
997 },
998 );
999
1000 assert_parse(
1001 &ctx,
1002 "alias: name(x: null) @skip(if: true) { child }",
1003 Field {
1004 alias: Some("alias"),
1005 name: "name",
1006 arguments: Arguments {
1007 children: Vec::from_iter_in(
1008 [Argument {
1009 name: "x",
1010 value: Value::Null,
1011 }],
1012 &ctx.arena,
1013 ),
1014 },
1015 directives: Directives {
1016 children: Vec::from_iter_in(
1017 [Directive {
1018 name: "skip",
1019 arguments: Arguments {
1020 children: Vec::from_iter_in(
1021 [Argument {
1022 name: "if",
1023 value: Value::Boolean(BooleanValue { value: true }),
1024 }],
1025 &ctx.arena,
1026 ),
1027 },
1028 }],
1029 &ctx.arena,
1030 ),
1031 },
1032 selection_set: SelectionSet {
1033 selections: Vec::from_iter_in(
1034 [Selection::Field(Field {
1035 alias: None,
1036 name: "child",
1037 arguments: Arguments {
1038 children: Vec::new_in(&ctx.arena),
1039 },
1040 directives: Directives {
1041 children: Vec::new_in(&ctx.arena),
1042 },
1043 selection_set: SelectionSet {
1044 selections: Vec::new_in(&ctx.arena),
1045 },
1046 })],
1047 &ctx.arena,
1048 ),
1049 },
1050 },
1051 );
1052
1053 assert_parse(
1054 &ctx,
1055 "parent { child }",
1056 Field {
1057 alias: None,
1058 name: "parent",
1059 arguments: Arguments {
1060 children: Vec::new_in(&ctx.arena),
1061 },
1062 directives: Directives {
1063 children: Vec::new_in(&ctx.arena),
1064 },
1065 selection_set: SelectionSet {
1066 selections: Vec::from_iter_in(
1067 [Selection::Field(Field {
1068 alias: None,
1069 name: "child",
1070 arguments: Arguments {
1071 children: Vec::new_in(&ctx.arena),
1072 },
1073 directives: Directives {
1074 children: Vec::new_in(&ctx.arena),
1075 },
1076 selection_set: SelectionSet {
1077 selections: Vec::new_in(&ctx.arena),
1078 },
1079 })],
1080 &ctx.arena,
1081 ),
1082 },
1083 },
1084 );
1085 }
1086
1087 #[test]
1088 fn fragment_spread() {
1089 let ctx = ASTContext::new();
1090
1091 assert_parse(
1092 &ctx,
1093 "... FragName",
1094 FragmentSpread {
1095 name: NamedType { name: "FragName" },
1096 directives: Directives {
1097 children: Vec::new_in(&ctx.arena),
1098 },
1099 },
1100 );
1101
1102 assert_parse(
1103 &ctx,
1104 "... FragName @skip(if: true)",
1105 FragmentSpread {
1106 name: NamedType { name: "FragName" },
1107 directives: Directives {
1108 children: Vec::from_iter_in(
1109 [Directive {
1110 name: "skip",
1111 arguments: Arguments {
1112 children: Vec::from_iter_in(
1113 [Argument {
1114 name: "if",
1115 value: Value::Boolean(BooleanValue { value: true }),
1116 }],
1117 &ctx.arena,
1118 ),
1119 },
1120 }],
1121 &ctx.arena,
1122 ),
1123 },
1124 },
1125 );
1126 }
1127
1128 #[test]
1129 fn inline_fragment() {
1130 let ctx = ASTContext::new();
1131
1132 assert_parse(
1133 &ctx,
1134 "... { __typename }",
1135 InlineFragment {
1136 type_condition: None,
1137 directives: Directives {
1138 children: Vec::new_in(&ctx.arena),
1139 },
1140 selection_set: SelectionSet {
1141 selections: Vec::from_iter_in(
1142 [Selection::Field(Field {
1143 alias: None,
1144 name: "__typename",
1145 arguments: Arguments {
1146 children: Vec::new_in(&ctx.arena),
1147 },
1148 directives: Directives {
1149 children: Vec::new_in(&ctx.arena),
1150 },
1151 selection_set: SelectionSet {
1152 selections: Vec::new_in(&ctx.arena),
1153 },
1154 })],
1155 &ctx.arena,
1156 ),
1157 },
1158 },
1159 );
1160
1161 assert_parse(
1162 &ctx,
1163 "... on Frag { __typename }",
1164 InlineFragment {
1165 type_condition: Some(NamedType { name: "Frag" }),
1166 directives: Directives {
1167 children: Vec::new_in(&ctx.arena),
1168 },
1169 selection_set: SelectionSet {
1170 selections: Vec::from_iter_in(
1171 [Selection::Field(Field {
1172 alias: None,
1173 name: "__typename",
1174 arguments: Arguments {
1175 children: Vec::new_in(&ctx.arena),
1176 },
1177 directives: Directives {
1178 children: Vec::new_in(&ctx.arena),
1179 },
1180 selection_set: SelectionSet {
1181 selections: Vec::new_in(&ctx.arena),
1182 },
1183 })],
1184 &ctx.arena,
1185 ),
1186 },
1187 },
1188 );
1189
1190 assert_parse(
1191 &ctx,
1192 "... @skip(if: true) { __typename }",
1193 InlineFragment {
1194 type_condition: None,
1195 directives: Directives {
1196 children: Vec::from_iter_in(
1197 [Directive {
1198 name: "skip",
1199 arguments: Arguments {
1200 children: Vec::from_iter_in(
1201 [Argument {
1202 name: "if",
1203 value: Value::Boolean(BooleanValue { value: true }),
1204 }],
1205 &ctx.arena,
1206 ),
1207 },
1208 }],
1209 &ctx.arena,
1210 ),
1211 },
1212 selection_set: SelectionSet {
1213 selections: Vec::from_iter_in(
1214 [Selection::Field(Field {
1215 alias: None,
1216 name: "__typename",
1217 arguments: Arguments {
1218 children: Vec::new_in(&ctx.arena),
1219 },
1220 directives: Directives {
1221 children: Vec::new_in(&ctx.arena),
1222 },
1223 selection_set: SelectionSet {
1224 selections: Vec::new_in(&ctx.arena),
1225 },
1226 })],
1227 &ctx.arena,
1228 ),
1229 },
1230 },
1231 );
1232
1233 assert_parse(
1234 &ctx,
1235 "...on Frag @skip(if: true) { __typename }",
1236 InlineFragment {
1237 type_condition: Some(NamedType { name: "Frag" }),
1238 directives: Directives {
1239 children: Vec::from_iter_in(
1240 [Directive {
1241 name: "skip",
1242 arguments: Arguments {
1243 children: Vec::from_iter_in(
1244 [Argument {
1245 name: "if",
1246 value: Value::Boolean(BooleanValue { value: true }),
1247 }],
1248 &ctx.arena,
1249 ),
1250 },
1251 }],
1252 &ctx.arena,
1253 ),
1254 },
1255 selection_set: SelectionSet {
1256 selections: Vec::from_iter_in(
1257 [Selection::Field(Field {
1258 alias: None,
1259 name: "__typename",
1260 arguments: Arguments {
1261 children: Vec::new_in(&ctx.arena),
1262 },
1263 directives: Directives {
1264 children: Vec::new_in(&ctx.arena),
1265 },
1266 selection_set: SelectionSet {
1267 selections: Vec::new_in(&ctx.arena),
1268 },
1269 })],
1270 &ctx.arena,
1271 ),
1272 },
1273 },
1274 );
1275 }
1276
1277 #[test]
1278 fn selections() {
1279 let ctx = ASTContext::new();
1280
1281 assert_parse(
1282 &ctx,
1283 "{ name, ... on Frag { name }, ... OtherFrag, ... { name }, name2: name }",
1284 SelectionSet {
1285 selections: Vec::from_iter_in(
1286 [
1287 Selection::Field(Field {
1288 alias: None,
1289 name: "name",
1290 arguments: Arguments {
1291 children: Vec::new_in(&ctx.arena),
1292 },
1293 directives: Directives {
1294 children: Vec::new_in(&ctx.arena),
1295 },
1296 selection_set: SelectionSet {
1297 selections: Vec::new_in(&ctx.arena),
1298 },
1299 }),
1300 Selection::InlineFragment(InlineFragment {
1301 type_condition: Some(NamedType { name: "Frag" }),
1302 directives: Directives {
1303 children: Vec::new_in(&ctx.arena),
1304 },
1305 selection_set: SelectionSet {
1306 selections: Vec::from_iter_in(
1307 [Selection::Field(Field {
1308 alias: None,
1309 name: "name",
1310 arguments: Arguments {
1311 children: Vec::new_in(&ctx.arena),
1312 },
1313 directives: Directives {
1314 children: Vec::new_in(&ctx.arena),
1315 },
1316 selection_set: SelectionSet {
1317 selections: Vec::new_in(&ctx.arena),
1318 },
1319 })],
1320 &ctx.arena,
1321 ),
1322 },
1323 }),
1324 Selection::FragmentSpread(FragmentSpread {
1325 name: NamedType { name: "OtherFrag" },
1326 directives: Directives {
1327 children: Vec::new_in(&ctx.arena),
1328 },
1329 }),
1330 Selection::InlineFragment(InlineFragment {
1331 type_condition: None,
1332 directives: Directives {
1333 children: Vec::new_in(&ctx.arena),
1334 },
1335 selection_set: SelectionSet {
1336 selections: Vec::from_iter_in(
1337 [Selection::Field(Field {
1338 alias: None,
1339 name: "name",
1340 arguments: Arguments {
1341 children: Vec::new_in(&ctx.arena),
1342 },
1343 directives: Directives {
1344 children: Vec::new_in(&ctx.arena),
1345 },
1346 selection_set: SelectionSet {
1347 selections: Vec::new_in(&ctx.arena),
1348 },
1349 })],
1350 &ctx.arena,
1351 ),
1352 },
1353 }),
1354 Selection::Field(Field {
1355 alias: Some("name2"),
1356 name: "name",
1357 arguments: Arguments {
1358 children: Vec::new_in(&ctx.arena),
1359 },
1360 directives: Directives {
1361 children: Vec::new_in(&ctx.arena),
1362 },
1363 selection_set: SelectionSet {
1364 selections: Vec::new_in(&ctx.arena),
1365 },
1366 }),
1367 ],
1368 &ctx.arena,
1369 ),
1370 },
1371 )
1372 }
1373
1374 #[test]
1375 fn types() {
1376 let ctx = ASTContext::new();
1377
1378 assert_parse(&ctx, "Type", Type::NamedType(NamedType { name: "Type" }));
1379
1380 assert_parse(
1381 &ctx,
1382 "Type!",
1383 Type::NonNullType(ctx.alloc(Type::NamedType(NamedType { name: "Type" }))),
1384 );
1385
1386 assert_parse(
1387 &ctx,
1388 "[Type!]",
1389 Type::ListType(ctx.alloc(Type::NonNullType(
1390 ctx.alloc(Type::NamedType(NamedType { name: "Type" })),
1391 ))),
1392 );
1393
1394 assert_parse(
1395 &ctx,
1396 "[Type!]!",
1397 Type::NonNullType(ctx.alloc(Type::ListType(ctx.alloc(Type::NonNullType(
1398 ctx.alloc(Type::NamedType(NamedType { name: "Type" })),
1399 ))))),
1400 );
1401
1402 assert_parse(
1403 &ctx,
1404 "[[Type]]",
1405 Type::ListType(ctx.alloc(Type::ListType(
1406 ctx.alloc(Type::NamedType(NamedType { name: "Type" })),
1407 ))),
1408 );
1409 }
1410
1411 #[test]
1412 fn var_definitions() {
1413 let ctx = ASTContext::new();
1414 assert_parse(
1415 &ctx,
1416 "#",
1417 VariableDefinitions {
1418 children: Vec::new_in(&ctx.arena),
1419 },
1420 );
1421
1422 VariableDefinitions::parse(&ctx, "($var: $var)").unwrap_err();
1424 VariableDefinitions::parse(&ctx, "($var: [$var])").unwrap_err();
1425
1426 assert_parse(
1427 &ctx,
1428 "($test: String)",
1429 VariableDefinitions {
1430 children: Vec::from_iter_in(
1431 [VariableDefinition {
1432 variable: Variable { name: "test" },
1433 of_type: Type::NamedType(NamedType { name: "String" }),
1434 default_value: Value::Null,
1435 directives: Directives {
1436 children: Vec::new_in(&ctx.arena),
1437 },
1438 }],
1439 &ctx.arena,
1440 ),
1441 },
1442 );
1443
1444 assert_parse(
1445 &ctx,
1446 "($test1: String, $test2: Int)",
1447 VariableDefinitions {
1448 children: Vec::from_iter_in(
1449 [
1450 VariableDefinition {
1451 variable: Variable { name: "test1" },
1452 of_type: Type::NamedType(NamedType { name: "String" }),
1453 default_value: Value::Null,
1454 directives: Directives {
1455 children: Vec::new_in(&ctx.arena),
1456 },
1457 },
1458 VariableDefinition {
1459 variable: Variable { name: "test2" },
1460 of_type: Type::NamedType(NamedType { name: "Int" }),
1461 default_value: Value::Null,
1462 directives: Directives {
1463 children: Vec::new_in(&ctx.arena),
1464 },
1465 },
1466 ],
1467 &ctx.arena,
1468 ),
1469 },
1470 );
1471
1472 assert_parse(
1473 &ctx,
1474 "$x: Int = 123",
1475 VariableDefinition {
1476 variable: Variable { name: "x" },
1477 of_type: Type::NamedType(NamedType { name: "Int" }),
1478 default_value: Value::Int(IntValue { value: "123" }),
1479 directives: Directives {
1480 children: Vec::new_in(&ctx.arena),
1481 },
1482 },
1483 );
1484
1485 assert_parse(
1486 &ctx,
1487 "$x: Int = 123 @test",
1488 VariableDefinition {
1489 variable: Variable { name: "x" },
1490 of_type: Type::NamedType(NamedType { name: "Int" }),
1491 default_value: Value::Int(IntValue { value: "123" }),
1492 directives: Directives {
1493 children: Vec::from_iter_in(
1494 [Directive {
1495 name: "test",
1496 arguments: Arguments {
1497 children: Vec::new_in(&ctx.arena),
1498 },
1499 }],
1500 &ctx.arena,
1501 ),
1502 },
1503 },
1504 );
1505
1506 assert_parse(
1507 &ctx,
1508 "$x: Int @test",
1509 VariableDefinition {
1510 variable: Variable { name: "x" },
1511 of_type: Type::NamedType(NamedType { name: "Int" }),
1512 default_value: Value::Null,
1513 directives: Directives {
1514 children: Vec::from_iter_in(
1515 [Directive {
1516 name: "test",
1517 arguments: Arguments {
1518 children: Vec::new_in(&ctx.arena),
1519 },
1520 }],
1521 &ctx.arena,
1522 ),
1523 },
1524 },
1525 );
1526 }
1527
1528 #[test]
1529 fn fragment() {
1530 let ctx = ASTContext::new();
1531
1532 assert_parse(
1533 &ctx,
1534 "fragment Test on Type { name }",
1535 FragmentDefinition {
1536 name: NamedType { name: "Test" },
1537 type_condition: NamedType { name: "Type" },
1538 directives: Directives {
1539 children: Vec::new_in(&ctx.arena),
1540 },
1541 selection_set: SelectionSet {
1542 selections: Vec::from_iter_in(
1543 [Selection::Field(Field {
1544 alias: None,
1545 name: "name",
1546 arguments: Arguments {
1547 children: Vec::new_in(&ctx.arena),
1548 },
1549 directives: Directives {
1550 children: Vec::new_in(&ctx.arena),
1551 },
1552 selection_set: SelectionSet {
1553 selections: Vec::new_in(&ctx.arena),
1554 },
1555 })],
1556 &ctx.arena,
1557 ),
1558 },
1559 },
1560 );
1561
1562 assert_parse(
1563 &ctx,
1564 "fragment Test on Type @test { name }",
1565 FragmentDefinition {
1566 name: NamedType { name: "Test" },
1567 type_condition: NamedType { name: "Type" },
1568 directives: Directives {
1569 children: Vec::from_iter_in(
1570 [Directive {
1571 name: "test",
1572 arguments: Arguments {
1573 children: Vec::new_in(&ctx.arena),
1574 },
1575 }],
1576 &ctx.arena,
1577 ),
1578 },
1579 selection_set: SelectionSet {
1580 selections: Vec::from_iter_in(
1581 [Selection::Field(Field {
1582 alias: None,
1583 name: "name",
1584 arguments: Arguments {
1585 children: Vec::new_in(&ctx.arena),
1586 },
1587 directives: Directives {
1588 children: Vec::new_in(&ctx.arena),
1589 },
1590 selection_set: SelectionSet {
1591 selections: Vec::new_in(&ctx.arena),
1592 },
1593 })],
1594 &ctx.arena,
1595 ),
1596 },
1597 },
1598 );
1599 }
1600
1601 #[test]
1602 fn operation_with_high_int_value() {
1603 let ctx = ASTContext::new();
1604
1605 assert_parse(
1606 &ctx,
1607 "query { field(id: 1002275100009989500000000000000000000000000000000000) }",
1608 OperationDefinition {
1609 operation: OperationKind::Query,
1610 name: None,
1611 variable_definitions: VariableDefinitions { children: Vec::new_in(&ctx.arena )},
1612 directives: Directives { children: Vec::new_in(&ctx.arena )},
1613 selection_set: SelectionSet{ selections: Vec::from_iter_in(
1614 [Selection::Field(Field {
1615 alias: None,
1616 name: "field",
1617 arguments: Arguments { children: Vec::from_iter_in(
1618 [Argument {
1619 name: "id",
1620 value: Value::Int(IntValue {
1621 value: "1002275100009989500000000000000000000000000000000000",
1622 }),
1623 }],
1624 &ctx.arena,
1625 )},
1626 directives: Directives { children: Vec::new_in(&ctx.arena )},
1627 selection_set: SelectionSet { selections: Vec::new_in(&ctx.arena )},
1628 })],
1629 &ctx.arena,
1630 )},
1631 },
1632 )
1633 }
1634
1635 #[test]
1636 fn operation() {
1637 let ctx = ASTContext::new();
1638
1639 assert_parse(
1640 &ctx,
1641 "{ name }",
1642 OperationDefinition {
1643 operation: OperationKind::Query,
1644 name: None,
1645 variable_definitions: VariableDefinitions {
1646 children: Vec::new_in(&ctx.arena),
1647 },
1648 directives: Directives {
1649 children: Vec::new_in(&ctx.arena),
1650 },
1651 selection_set: SelectionSet {
1652 selections: Vec::from_iter_in(
1653 [Selection::Field(Field {
1654 alias: None,
1655 name: "name",
1656 arguments: Arguments {
1657 children: Vec::new_in(&ctx.arena),
1658 },
1659 directives: Directives {
1660 children: Vec::new_in(&ctx.arena),
1661 },
1662 selection_set: SelectionSet {
1663 selections: Vec::new_in(&ctx.arena),
1664 },
1665 })],
1666 &ctx.arena,
1667 ),
1668 },
1669 },
1670 );
1671
1672 assert_parse(
1673 &ctx,
1674 "query { name }",
1675 OperationDefinition {
1676 operation: OperationKind::Query,
1677 name: None,
1678 variable_definitions: VariableDefinitions {
1679 children: Vec::new_in(&ctx.arena),
1680 },
1681 directives: Directives {
1682 children: Vec::new_in(&ctx.arena),
1683 },
1684 selection_set: SelectionSet {
1685 selections: Vec::from_iter_in(
1686 [Selection::Field(Field {
1687 alias: None,
1688 name: "name",
1689 arguments: Arguments {
1690 children: Vec::new_in(&ctx.arena),
1691 },
1692 directives: Directives {
1693 children: Vec::new_in(&ctx.arena),
1694 },
1695 selection_set: SelectionSet {
1696 selections: Vec::new_in(&ctx.arena),
1697 },
1698 })],
1699 &ctx.arena,
1700 ),
1701 },
1702 },
1703 );
1704
1705 assert_parse(
1706 &ctx,
1707 "mutation { name }",
1708 OperationDefinition {
1709 operation: OperationKind::Mutation,
1710 name: None,
1711 variable_definitions: VariableDefinitions {
1712 children: Vec::new_in(&ctx.arena),
1713 },
1714 directives: Directives {
1715 children: Vec::new_in(&ctx.arena),
1716 },
1717 selection_set: SelectionSet {
1718 selections: Vec::from_iter_in(
1719 [Selection::Field(Field {
1720 alias: None,
1721 name: "name",
1722 arguments: Arguments {
1723 children: Vec::new_in(&ctx.arena),
1724 },
1725 directives: Directives {
1726 children: Vec::new_in(&ctx.arena),
1727 },
1728 selection_set: SelectionSet {
1729 selections: Vec::new_in(&ctx.arena),
1730 },
1731 })],
1732 &ctx.arena,
1733 ),
1734 },
1735 },
1736 );
1737
1738 assert_parse(
1739 &ctx,
1740 "subscription { name }",
1741 OperationDefinition {
1742 operation: OperationKind::Subscription,
1743 name: None,
1744 variable_definitions: VariableDefinitions {
1745 children: Vec::new_in(&ctx.arena),
1746 },
1747 directives: Directives {
1748 children: Vec::new_in(&ctx.arena),
1749 },
1750 selection_set: SelectionSet {
1751 selections: Vec::from_iter_in(
1752 [Selection::Field(Field {
1753 alias: None,
1754 name: "name",
1755 arguments: Arguments {
1756 children: Vec::new_in(&ctx.arena),
1757 },
1758 directives: Directives {
1759 children: Vec::new_in(&ctx.arena),
1760 },
1761 selection_set: SelectionSet {
1762 selections: Vec::new_in(&ctx.arena),
1763 },
1764 })],
1765 &ctx.arena,
1766 ),
1767 },
1768 },
1769 );
1770
1771 assert_parse(
1772 &ctx,
1773 "query Name { name }",
1774 OperationDefinition {
1775 operation: OperationKind::Query,
1776 name: Some(NamedType { name: "Name" }),
1777 variable_definitions: VariableDefinitions {
1778 children: Vec::new_in(&ctx.arena),
1779 },
1780 directives: Directives {
1781 children: Vec::new_in(&ctx.arena),
1782 },
1783 selection_set: SelectionSet {
1784 selections: Vec::from_iter_in(
1785 [Selection::Field(Field {
1786 alias: None,
1787 name: "name",
1788 arguments: Arguments {
1789 children: Vec::new_in(&ctx.arena),
1790 },
1791 directives: Directives {
1792 children: Vec::new_in(&ctx.arena),
1793 },
1794 selection_set: SelectionSet {
1795 selections: Vec::new_in(&ctx.arena),
1796 },
1797 })],
1798 &ctx.arena,
1799 ),
1800 },
1801 },
1802 );
1803
1804 assert_parse(
1805 &ctx,
1806 "query Name($test: Int) { name }",
1807 OperationDefinition {
1808 operation: OperationKind::Query,
1809 name: Some(NamedType { name: "Name" }),
1810 variable_definitions: VariableDefinitions {
1811 children: Vec::from_iter_in(
1812 [VariableDefinition {
1813 variable: Variable { name: "test" },
1814 of_type: Type::NamedType(NamedType { name: "Int" }),
1815 directives: Directives {
1816 children: Vec::new_in(&ctx.arena),
1817 },
1818 default_value: Value::Null,
1819 }],
1820 &ctx.arena,
1821 ),
1822 },
1823 directives: Directives {
1824 children: Vec::new_in(&ctx.arena),
1825 },
1826 selection_set: SelectionSet {
1827 selections: Vec::from_iter_in(
1828 [Selection::Field(Field {
1829 alias: None,
1830 name: "name",
1831 arguments: Arguments {
1832 children: Vec::new_in(&ctx.arena),
1833 },
1834 directives: Directives {
1835 children: Vec::new_in(&ctx.arena),
1836 },
1837 selection_set: SelectionSet {
1838 selections: Vec::new_in(&ctx.arena),
1839 },
1840 })],
1841 &ctx.arena,
1842 ),
1843 },
1844 },
1845 );
1846
1847 assert_parse(
1848 &ctx,
1849 "query Name @test { name }",
1850 OperationDefinition {
1851 operation: OperationKind::Query,
1852 name: Some(NamedType { name: "Name" }),
1853 variable_definitions: VariableDefinitions {
1854 children: Vec::new_in(&ctx.arena),
1855 },
1856 directives: Directives {
1857 children: Vec::from_iter_in(
1858 [Directive {
1859 name: "test",
1860 arguments: Arguments {
1861 children: Vec::new_in(&ctx.arena),
1862 },
1863 }],
1864 &ctx.arena,
1865 ),
1866 },
1867 selection_set: SelectionSet {
1868 selections: Vec::from_iter_in(
1869 [Selection::Field(Field {
1870 alias: None,
1871 name: "name",
1872 arguments: Arguments {
1873 children: Vec::new_in(&ctx.arena),
1874 },
1875 directives: Directives {
1876 children: Vec::new_in(&ctx.arena),
1877 },
1878 selection_set: SelectionSet {
1879 selections: Vec::new_in(&ctx.arena),
1880 },
1881 })],
1882 &ctx.arena,
1883 ),
1884 },
1885 },
1886 );
1887 }
1888}