apollo_parser/parser/grammar/
object.rs1#![allow(clippy::needless_return)]
2
3use crate::parser::grammar::description;
4use crate::parser::grammar::directive;
5use crate::parser::grammar::field;
6use crate::parser::grammar::name;
7use crate::parser::grammar::ty;
8use crate::parser::grammar::value::Constness;
9use crate::Parser;
10use crate::SyntaxKind;
11use crate::TokenKind;
12use crate::S;
13use crate::T;
14
15pub(crate) fn object_type_definition(p: &mut Parser) {
20 let _g = p.start_node(SyntaxKind::OBJECT_TYPE_DEFINITION);
21
22 if let Some(TokenKind::StringValue) = p.peek() {
23 description::description(p);
24 }
25
26 if let Some("type") = p.peek_data() {
27 p.bump(SyntaxKind::type_KW);
28 }
29
30 match p.peek() {
31 Some(TokenKind::Name) => name::name(p),
32 _ => p.err("expected a name"),
33 }
34
35 if let Some(TokenKind::Name) = p.peek() {
36 if p.peek_data().unwrap() == "implements" {
37 implements_interfaces(p);
38 }
39 }
40
41 if let Some(T![@]) = p.peek() {
42 directive::directives(p, Constness::Const);
43 }
44
45 if let Some(T!['{']) = p.peek() {
46 field::fields_definition(p);
47 }
48}
49
50pub(crate) fn object_type_extension(p: &mut Parser) {
57 let _g = p.start_node(SyntaxKind::OBJECT_TYPE_EXTENSION);
58 p.bump(SyntaxKind::extend_KW);
59 p.bump(SyntaxKind::type_KW);
60
61 let mut meets_requirements = false;
64
65 match p.peek() {
66 Some(TokenKind::Name) => name::name(p),
67 _ => p.err("expected a Name"),
68 }
69
70 if let Some("implements") = p.peek_data() {
71 meets_requirements = true;
72 implements_interfaces(p);
73 }
74
75 if let Some(T![@]) = p.peek() {
76 meets_requirements = true;
77 directive::directives(p, Constness::Const)
78 }
79
80 if let Some(T!['{']) = p.peek() {
81 meets_requirements = true;
82 field::fields_definition(p)
83 }
84
85 if !meets_requirements {
86 p.err("expected an Implements Interface, Directives or a Fields Definition");
87 }
88}
89
90pub(crate) fn implements_interfaces(p: &mut Parser) {
96 let _g = p.start_node(SyntaxKind::IMPLEMENTS_INTERFACES);
97 p.bump(SyntaxKind::implements_KW);
98
99 p.parse_separated_list(T![&], S![&], |p| {
100 if let Some(TokenKind::Name) = p.peek() {
101 ty::named_type(p);
102 } else {
103 p.err("expected an Interface name");
104 }
105 });
106}
107
108#[cfg(test)]
109mod test {
110 use super::*;
111 use crate::cst;
112
113 #[test]
114 fn object_type_definition() {
115 let input = "
116type Business implements NamedEntity & ValuedEntity & CatEntity {
117 name: String
118}";
119 let parser = Parser::new(input);
120 let cst = parser.parse();
121 assert_eq!(0, cst.errors().len());
122
123 let doc = cst.document();
124
125 for def in doc.definitions() {
126 if let cst::Definition::ObjectTypeDefinition(interface_type) = def {
127 assert_eq!(interface_type.name().unwrap().text(), "Business");
128 for implements_interfaces in interface_type
129 .implements_interfaces()
130 .unwrap()
131 .named_types()
132 {
133 println!("{}", implements_interfaces.name().unwrap().text());
135 }
136 }
137 }
138 }
139}