1use std::str::FromStr;
2
3pub use crate::common::{Directive, Name, Type, Value};
4use crate::position::Pos;
5
6pub type NamedType = String;
7
8#[derive(Debug, Clone, Default, PartialEq)]
9pub struct Document {
10 pub definitions: Vec<Definition>,
11}
12
13#[derive(Debug, Clone, PartialEq)]
14pub enum Definition {
15 SchemaDefinition(SchemaDefinition),
16 TypeDefinition(TypeDefinition),
17 TypeExtension(TypeExtension),
18 DirectiveDefinition(DirectiveDefinition),
19}
20
21#[derive(Debug, Clone, Default, PartialEq)]
22pub struct SchemaDefinition {
23 pub position: Pos,
24 pub directives: Vec<Directive>,
25 pub query: Option<NamedType>,
26 pub mutation: Option<NamedType>,
27 pub subscription: Option<NamedType>,
28}
29
30#[derive(Debug, Clone, PartialEq)]
31pub enum TypeDefinition {
32 Scalar(ScalarType),
33 Object(ObjectType),
34 Interface(InterfaceType),
35 Union(UnionType),
36 Enum(EnumType),
37 InputObject(InputObjectType),
38}
39
40#[derive(Debug, Clone, PartialEq)]
41pub enum TypeExtension {
42 Scalar(ScalarTypeExtension),
43 Object(ObjectTypeExtension),
44 Interface(InterfaceTypeExtension),
45 Union(UnionTypeExtension),
46 Enum(EnumTypeExtension),
47 InputObject(InputObjectTypeExtension),
48}
49
50#[derive(Debug, Clone, PartialEq)]
51pub struct ScalarType {
52 pub position: Pos,
53 pub description: Option<String>,
54 pub name: Name,
55 pub directives: Vec<Directive>,
56}
57
58impl ScalarType {
59 pub fn new(name: Name) -> Self {
60 Self {
61 position: Pos::default(),
62 description: None,
63 name,
64 directives: vec![],
65 }
66 }
67}
68
69#[derive(Debug, Clone, PartialEq)]
70pub struct ScalarTypeExtension {
71 pub position: Pos,
72 pub name: Name,
73 pub directives: Vec<Directive>,
74}
75
76impl ScalarTypeExtension {
77 pub fn new(name: Name) -> Self {
78 Self {
79 position: Pos::default(),
80 name,
81 directives: vec![],
82 }
83 }
84}
85
86#[derive(Debug, Clone, PartialEq)]
87pub struct ObjectType {
88 pub position: Pos,
89 pub description: Option<String>,
90 pub name: Name,
91 pub implements_interfaces: Vec<NamedType>,
92 pub directives: Vec<Directive>,
93 pub fields: Vec<Field>,
94}
95
96impl ObjectType {
97 pub fn new(name: Name) -> Self {
98 Self {
99 position: Pos::default(),
100 description: None,
101 name,
102 implements_interfaces: vec![],
103 directives: vec![],
104 fields: vec![],
105 }
106 }
107}
108
109#[derive(Debug, Clone, PartialEq)]
110pub struct ObjectTypeExtension {
111 pub position: Pos,
112 pub name: Name,
113 pub implements_interfaces: Vec<NamedType>,
114 pub directives: Vec<Directive>,
115 pub fields: Vec<Field>,
116}
117
118impl ObjectTypeExtension {
119 pub fn new(name: Name) -> Self {
120 Self {
121 position: Pos::default(),
122 name,
123 implements_interfaces: vec![],
124 directives: vec![],
125 fields: vec![],
126 }
127 }
128}
129
130#[derive(Debug, Clone, PartialEq)]
131pub struct Field {
132 pub position: Pos,
133 pub description: Option<String>,
134 pub name: Name,
135 pub arguments: Vec<InputValue>,
136 pub field_type: Type,
137 pub directives: Vec<Directive>,
138}
139
140#[derive(Debug, Clone, PartialEq)]
141pub struct InputValue {
142 pub position: Pos,
143 pub description: Option<String>,
144 pub name: Name,
145 pub value_type: Type,
146 pub default_value: Option<Value>,
147 pub directives: Vec<Directive>,
148}
149
150#[derive(Debug, Clone, PartialEq)]
151pub struct InterfaceType {
152 pub position: Pos,
153 pub description: Option<String>,
154 pub name: Name,
155 pub directives: Vec<Directive>,
156 pub fields: Vec<Field>,
157}
158
159impl InterfaceType {
160 pub fn new(name: Name) -> Self {
161 Self {
162 position: Pos::default(),
163 description: None,
164 name,
165 directives: vec![],
166 fields: vec![],
167 }
168 }
169}
170
171#[derive(Debug, Clone, PartialEq)]
172pub struct InterfaceTypeExtension {
173 pub position: Pos,
174 pub name: Name,
175 pub directives: Vec<Directive>,
176 pub fields: Vec<Field>,
177}
178
179impl InterfaceTypeExtension {
180 pub fn new(name: Name) -> Self {
181 Self {
182 position: Pos::default(),
183 name,
184 directives: vec![],
185 fields: vec![],
186 }
187 }
188}
189
190#[derive(Debug, Clone, PartialEq)]
191pub struct UnionType {
192 pub position: Pos,
193 pub description: Option<String>,
194 pub name: Name,
195 pub directives: Vec<Directive>,
196 pub types: Vec<NamedType>,
197}
198
199impl UnionType {
200 pub fn new(name: Name) -> Self {
201 Self {
202 position: Pos::default(),
203 description: None,
204 name,
205 directives: vec![],
206 types: vec![],
207 }
208 }
209}
210
211#[derive(Debug, Clone, PartialEq)]
212pub struct UnionTypeExtension {
213 pub position: Pos,
214 pub name: Name,
215 pub directives: Vec<Directive>,
216 pub types: Vec<NamedType>,
217}
218
219impl UnionTypeExtension {
220 pub fn new(name: Name) -> Self {
221 Self {
222 position: Pos::default(),
223 name,
224 directives: vec![],
225 types: vec![],
226 }
227 }
228}
229
230#[derive(Debug, Clone, PartialEq)]
231pub struct EnumType {
232 pub position: Pos,
233 pub description: Option<String>,
234 pub name: Name,
235 pub directives: Vec<Directive>,
236 pub values: Vec<EnumValue>,
237}
238
239impl EnumType {
240 pub fn new(name: Name) -> Self {
241 Self {
242 position: Pos::default(),
243 description: None,
244 name,
245 directives: vec![],
246 values: vec![],
247 }
248 }
249}
250
251#[derive(Debug, Clone, PartialEq)]
252pub struct EnumValue {
253 pub position: Pos,
254 pub description: Option<String>,
255 pub name: Name,
256 pub directives: Vec<Directive>,
257}
258
259impl EnumValue {
260 pub fn new(name: Name) -> Self {
261 Self {
262 position: Pos::default(),
263 description: None,
264 name,
265 directives: vec![],
266 }
267 }
268}
269
270#[derive(Debug, Clone, PartialEq)]
271pub struct EnumTypeExtension {
272 pub position: Pos,
273 pub name: Name,
274 pub directives: Vec<Directive>,
275 pub values: Vec<EnumValue>,
276}
277
278impl EnumTypeExtension {
279 pub fn new(name: Name) -> Self {
280 Self {
281 position: Pos::default(),
282 name,
283 directives: vec![],
284 values: vec![],
285 }
286 }
287}
288
289#[derive(Debug, Clone, PartialEq)]
290pub struct InputObjectType {
291 pub position: Pos,
292 pub description: Option<String>,
293 pub name: Name,
294 pub directives: Vec<Directive>,
295 pub fields: Vec<InputValue>,
296}
297
298impl InputObjectType {
299 pub fn new(name: Name) -> Self {
300 Self {
301 position: Pos::default(),
302 description: None,
303 name,
304 directives: vec![],
305 fields: vec![],
306 }
307 }
308}
309
310#[derive(Debug, Clone, PartialEq)]
311pub struct InputObjectTypeExtension {
312 pub position: Pos,
313 pub name: Name,
314 pub directives: Vec<Directive>,
315 pub fields: Vec<InputValue>,
316}
317
318impl InputObjectTypeExtension {
319 pub fn new(name: Name) -> Self {
320 Self {
321 position: Pos::default(),
322 name,
323 directives: vec![],
324 fields: vec![],
325 }
326 }
327}
328
329#[derive(Debug, Clone, PartialEq, Eq, Hash)]
330pub enum DirectiveLocation {
331 Query,
333 Mutation,
334 Subscription,
335 Field,
336 FragmentDefinition,
337 FragmentSpread,
338 InlineFragment,
339
340 Schema,
342 Scalar,
343 Object,
344 FieldDefinition,
345 ArgumentDefinition,
346 Interface,
347 Union,
348 Enum,
349 EnumValue,
350 InputObject,
351 InputFieldDefinition,
352}
353
354#[derive(Debug, Clone, PartialEq)]
355pub struct DirectiveDefinition {
356 pub position: Pos,
357 pub description: Option<String>,
358 pub name: Name,
359 pub arguments: Vec<InputValue>,
360 pub repeatable: bool,
361 pub locations: Vec<DirectiveLocation>,
362}
363
364impl DirectiveDefinition {
365 pub fn new(name: Name) -> Self {
366 Self {
367 position: Pos::default(),
368 description: None,
369 name,
370 arguments: vec![],
371 repeatable: false,
372 locations: vec![],
373 }
374 }
375}
376
377impl DirectiveLocation {
378 pub fn as_str(&self) -> &'static str {
380 use self::DirectiveLocation::*;
381 match *self {
382 Query => "QUERY",
383 Mutation => "MUTATION",
384 Subscription => "SUBSCRIPTION",
385 Field => "FIELD",
386 FragmentDefinition => "FRAGMENT_DEFINITION",
387 FragmentSpread => "FRAGMENT_SPREAD",
388 InlineFragment => "INLINE_FRAGMENT",
389 Schema => "SCHEMA",
390 Scalar => "SCALAR",
391 Object => "OBJECT",
392 FieldDefinition => "FIELD_DEFINITION",
393 ArgumentDefinition => "ARGUMENT_DEFINITION",
394 Interface => "INTERFACE",
395 Union => "UNION",
396 Enum => "ENUM",
397 EnumValue => "ENUM_VALUE",
398 InputObject => "INPUT_OBJECT",
399 InputFieldDefinition => "INPUT_FIELD_DEFINITION",
400 }
401 }
402
403 pub fn is_query(&self) -> bool {
405 use self::DirectiveLocation::*;
406 match *self {
407 Query | Mutation | Subscription | Field | FragmentDefinition | FragmentSpread
408 | InlineFragment => true,
409
410 Schema | Scalar | Object | FieldDefinition | ArgumentDefinition | Interface | Union
411 | Enum | EnumValue | InputObject | InputFieldDefinition => false,
412 }
413 }
414
415 pub fn is_schema(&self) -> bool {
417 !self.is_query()
418 }
419}
420
421#[derive(Debug, thiserror::Error)]
422#[error("invalid directive location")]
423pub struct InvalidDirectiveLocation;
424
425impl FromStr for DirectiveLocation {
426 type Err = InvalidDirectiveLocation;
427 fn from_str(s: &str) -> Result<DirectiveLocation, InvalidDirectiveLocation> {
428 use self::DirectiveLocation::*;
429 let val = match s {
430 "QUERY" => Query,
431 "MUTATION" => Mutation,
432 "SUBSCRIPTION" => Subscription,
433 "FIELD" => Field,
434 "FRAGMENT_DEFINITION" => FragmentDefinition,
435 "FRAGMENT_SPREAD" => FragmentSpread,
436 "INLINE_FRAGMENT" => InlineFragment,
437 "SCHEMA" => Schema,
438 "SCALAR" => Scalar,
439 "OBJECT" => Object,
440 "FIELD_DEFINITION" => FieldDefinition,
441 "ARGUMENT_DEFINITION" => ArgumentDefinition,
442 "INTERFACE" => Interface,
443 "UNION" => Union,
444 "ENUM" => Enum,
445 "ENUM_VALUE" => EnumValue,
446 "INPUT_OBJECT" => InputObject,
447 "INPUT_FIELD_DEFINITION" => InputFieldDefinition,
448 _ => return Err(InvalidDirectiveLocation),
449 };
450
451 Ok(val)
452 }
453}