1pub mod common;
2pub mod executable;
3pub mod type_system;
4pub mod values;
5
6mod errors;
7mod lexer;
8mod span;
9
10#[allow(clippy::all)]
11mod parser;
12
13#[cfg(feature = "print")]
14pub mod printing;
15
16#[cfg(feature = "report")]
17pub use errors::Report;
18
19pub use self::{
20 errors::Error,
21 executable::ExecutableDocument,
22 span::Span,
23 type_system::TypeSystemDocument,
24 values::{ConstValue, Value},
25};
26
27pub fn parse_type_system_document(input: &str) -> Result<TypeSystemDocument, Error> {
28 if input.trim().is_empty() {
29 return Err(Error::EmptyTypeSystemDocument);
30 }
31
32 let lexer = lexer::Lexer::new(input);
33 let mut ast = type_system::writer::TypeSystemAstWriter::new();
34
35 parser::TypeSystemDocumentParser::new().parse(input, &mut ast, lexer)?;
36
37 Ok(ast.finish())
38}
39
40pub fn parse_executable_document(input: &str) -> Result<ExecutableDocument, Error> {
41 if input.trim().is_empty() {
42 return Err(Error::EmptyExecutableDocument);
43 }
44
45 let lexer = lexer::Lexer::new(input);
46 let mut ast = executable::writer::ExecutableAstWriter::new();
47
48 parser::ExecutableDocumentParser::new().parse(input, &mut ast, lexer)?;
49
50 Ok(ast.finish())
51}
52
53trait AstLookup<Id> {
54 type Output: ?Sized;
55
56 fn lookup(&self, index: Id) -> &Self::Output;
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn it_works() {
65 insta::assert_snapshot!(
66 parse_type_system_document("schema { query:Query }").unwrap().to_sdl_pretty(),
67 @r###"
68 schema {
69 query: Query
70 }
71 "###
72 );
73 }
74
75 #[test]
76 fn test_basic_object() {
77 insta::assert_snapshot!(
78 parse_type_system_document(r#"
79 type MyType implements Blah & Bloo @hello {
80 field: Whatever @hello(name: ["string"]),
81 other: [[Int!]]!
82 }"#
83 ).unwrap().to_sdl_pretty(),
84 @r###"
85 type MyType implements Blah & Bloo @hello {
86 field: Whatever @hello(name: ["string"])
87 other: [[Int!]]!
88 }
89 "###
90 );
91 }
92
93 #[test]
94 fn test_basic_interface() {
95 insta::assert_snapshot!(
96 parse_type_system_document(r#"
97 interface MyType implements Blah & Bloo @hello {
98 field: Whatever @hello(name: ["string"]),
99 other: [[Int!]]!
100 }"#
101 ).unwrap().to_sdl_pretty(),
102 @r###"
103 interface MyType implements Blah & Bloo @hello {
104 field: Whatever @hello(name: ["string"])
105 other: [[Int!]]!
106 }
107 "###
108 );
109 }
110
111 #[test]
112 fn test_basic_union() {
113 insta::assert_snapshot!(
114 parse_type_system_document(r#"
115 union MyType = Blah | Bloo
116 "#
117 ).unwrap().to_sdl_pretty(),
118 @r###"
119 union MyType = Blah | Bloo
120
121 "###
122 );
123 }
124
125 #[test]
126 fn test_basic_scalar() {
127 insta::assert_snapshot!(
128 parse_type_system_document(r#"
129 scalar MyType @hello(there: [{thing: "other"}])
130 "#
131 ).unwrap().to_sdl_pretty(),
132 @r###"
133 scalar MyType @hello(there: [{ thing: "other" }])
134 "###
135 );
136 }
137
138 #[test]
139 fn test_basic_enum() {
140 insta::assert_snapshot!(
141 parse_type_system_document(r#"
142 enum MyEnum {
143 BLAH,
144 BLOO
145 }
146 "#
147 ).unwrap().to_sdl_pretty(),
148 @r###"
149 enum MyEnum {
150 BLAH
151 BLOO
152 }
153 "###
154 );
155 }
156
157 #[test]
158 fn test_schema_field() {
159 insta::assert_snapshot!(
161 parse_type_system_document( "type MyType { query: String }").unwrap().to_sdl_pretty(),
162 @r###"
163 type MyType {
164 query: String
165 }
166 "###
167 )
168 }
169
170 #[test]
171 fn test_input() {
172 insta::assert_snapshot!(
173 parse_type_system_document(
174 r#"
175 "I am a description"
176 input MyType @hello { query: String = "Hello" }
177 "#
178 ).unwrap().to_sdl_pretty(),
179 @r###"
180 "I am a description"
181 input MyType @hello {
182 query: String = "Hello"
183 }
184 "###
185 );
186 }
187}