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