Skip to main content

cynic_parser/
lib.rs

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        // Use a keyword as a field name and make sure it's fine
162        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}