gurkle_parser/schema/
format.rs

1use std::fmt;
2
3use crate::format::{format_directives, Displayable, Formatter, Style};
4
5use crate::schema::ast::*;
6
7impl Document {
8    /// Format a document according to style
9    pub fn format(&self, style: &Style) -> String {
10        let mut formatter = Formatter::new(style);
11        self.display(&mut formatter);
12        formatter.into_string()
13    }
14}
15
16fn to_string<T: Displayable>(v: &T) -> String {
17    let style = Style::default();
18    let mut formatter = Formatter::new(&style);
19    v.display(&mut formatter);
20    formatter.into_string()
21}
22
23fn description(description: &Option<String>, f: &mut Formatter) {
24    if let Some(ref descr) = *description {
25        f.indent();
26        f.write_quoted(descr);
27        f.endline();
28    }
29}
30
31impl Displayable for Document {
32    fn display(&self, f: &mut Formatter) {
33        for item in &self.definitions {
34            item.display(f);
35        }
36    }
37}
38
39impl Displayable for Definition {
40    fn display(&self, f: &mut Formatter) {
41        f.margin();
42        match *self {
43            Definition::SchemaDefinition(ref s) => s.display(f),
44            Definition::TypeDefinition(ref t) => t.display(f),
45            Definition::TypeExtension(ref e) => e.display(f),
46            Definition::DirectiveDefinition(ref d) => d.display(f),
47        }
48    }
49}
50
51impl Displayable for SchemaDefinition {
52    fn display(&self, f: &mut Formatter) {
53        f.indent();
54        f.write("schema");
55        format_directives(&self.directives, f);
56        f.write(" ");
57        f.start_block();
58        if let Some(ref q) = self.query {
59            f.indent();
60            f.write("query: ");
61            f.write(q);
62            f.endline();
63        }
64        if let Some(ref m) = self.mutation {
65            f.indent();
66            f.write("mutation: ");
67            f.write(m);
68            f.endline();
69        }
70        if let Some(ref s) = self.subscription {
71            f.indent();
72            f.write("subscription: ");
73            f.write(s);
74            f.endline();
75        }
76        f.end_block();
77    }
78}
79
80impl Displayable for TypeDefinition {
81    fn display(&self, f: &mut Formatter) {
82        match *self {
83            TypeDefinition::Scalar(ref s) => s.display(f),
84            TypeDefinition::Object(ref o) => o.display(f),
85            TypeDefinition::Interface(ref i) => i.display(f),
86            TypeDefinition::Union(ref u) => u.display(f),
87            TypeDefinition::Enum(ref e) => e.display(f),
88            TypeDefinition::InputObject(ref i) => i.display(f),
89        }
90    }
91}
92
93impl Displayable for ScalarType {
94    fn display(&self, f: &mut Formatter) {
95        description(&self.description, f);
96        f.indent();
97        f.write("scalar ");
98        f.write(&self.name);
99        format_directives(&self.directives, f);
100        f.endline();
101    }
102}
103
104impl Displayable for ScalarTypeExtension {
105    fn display(&self, f: &mut Formatter) {
106        f.indent();
107        f.write("extend scalar ");
108        f.write(&self.name);
109        format_directives(&self.directives, f);
110        f.endline();
111    }
112}
113
114fn format_fields(fields: &[Field], f: &mut Formatter) {
115    if !fields.is_empty() {
116        f.write(" ");
117        f.start_block();
118        for fld in fields {
119            fld.display(f);
120        }
121        f.end_block();
122    } else {
123        f.endline();
124    }
125}
126
127impl Displayable for ObjectType {
128    fn display(&self, f: &mut Formatter) {
129        description(&self.description, f);
130        f.indent();
131        f.write("type ");
132        f.write(&self.name);
133        if !self.implements_interfaces.is_empty() {
134            f.write(" implements ");
135            f.write(&self.implements_interfaces[0]);
136            for name in &self.implements_interfaces[1..] {
137                f.write(" & ");
138                f.write(name);
139            }
140        }
141        format_directives(&self.directives, f);
142        format_fields(&self.fields, f);
143    }
144}
145
146impl Displayable for ObjectTypeExtension {
147    fn display(&self, f: &mut Formatter) {
148        f.indent();
149        f.write("extend type ");
150        f.write(&self.name);
151        if !self.implements_interfaces.is_empty() {
152            f.write(" implements ");
153            f.write(&self.implements_interfaces[0]);
154            for name in &self.implements_interfaces[1..] {
155                f.write(" & ");
156                f.write(name);
157            }
158        }
159        format_directives(&self.directives, f);
160        format_fields(&self.fields, f);
161    }
162}
163
164impl Displayable for InputValue {
165    fn display(&self, f: &mut Formatter) {
166        if let Some(ref descr) = self.description {
167            f.write_quoted(descr);
168            f.write(" ");
169        }
170        f.write(&self.name);
171        f.write(": ");
172        self.value_type.display(f);
173        if let Some(ref def) = self.default_value {
174            f.write(" = ");
175            def.display(f);
176        }
177        format_directives(&self.directives, f);
178    }
179}
180
181fn format_arguments(arguments: &[InputValue], f: &mut Formatter) {
182    if !arguments.is_empty() {
183        f.write("(");
184        arguments[0].display(f);
185        for arg in &arguments[1..] {
186            f.write(", ");
187            arg.display(f);
188        }
189        f.write(")");
190    }
191}
192
193impl Displayable for Field {
194    fn display(&self, f: &mut Formatter) {
195        description(&self.description, f);
196        f.indent();
197        f.write(&self.name);
198        format_arguments(&self.arguments, f);
199        f.write(": ");
200        self.field_type.display(f);
201        format_directives(&self.directives, f);
202        f.endline();
203    }
204}
205
206impl Displayable for InterfaceType {
207    fn display(&self, f: &mut Formatter) {
208        description(&self.description, f);
209        f.indent();
210        f.write("interface ");
211        f.write(&self.name);
212        format_directives(&self.directives, f);
213        format_fields(&self.fields, f);
214    }
215}
216
217impl Displayable for InterfaceTypeExtension {
218    fn display(&self, f: &mut Formatter) {
219        f.indent();
220        f.write("extend interface ");
221        f.write(&self.name);
222        format_directives(&self.directives, f);
223        format_fields(&self.fields, f);
224    }
225}
226
227impl Displayable for UnionType {
228    fn display(&self, f: &mut Formatter) {
229        description(&self.description, f);
230        f.indent();
231        f.write("union ");
232        f.write(&self.name);
233        format_directives(&self.directives, f);
234        if !self.types.is_empty() {
235            f.write(" = ");
236            f.write(&self.types[0]);
237            for typ in &self.types[1..] {
238                f.write(" | ");
239                f.write(typ);
240            }
241        }
242        f.endline();
243    }
244}
245
246impl Displayable for UnionTypeExtension {
247    fn display(&self, f: &mut Formatter) {
248        f.indent();
249        f.write("extend union ");
250        f.write(&self.name);
251        format_directives(&self.directives, f);
252        if !self.types.is_empty() {
253            f.write(" = ");
254            f.write(&self.types[0]);
255            for typ in &self.types[1..] {
256                f.write(" | ");
257                f.write(typ);
258            }
259        }
260        f.endline();
261    }
262}
263
264impl Displayable for EnumType {
265    fn display(&self, f: &mut Formatter) {
266        description(&self.description, f);
267        f.indent();
268        f.write("enum ");
269        f.write(&self.name);
270        format_directives(&self.directives, f);
271        if !self.values.is_empty() {
272            f.write(" ");
273            f.start_block();
274            for val in &self.values {
275                f.indent();
276                if let Some(ref descr) = val.description {
277                    f.write_quoted(descr);
278                    f.write(" ");
279                }
280                f.write(&val.name);
281                format_directives(&val.directives, f);
282                f.endline();
283            }
284            f.end_block();
285        } else {
286            f.endline();
287        }
288    }
289}
290
291impl Displayable for EnumTypeExtension {
292    fn display(&self, f: &mut Formatter) {
293        f.indent();
294        f.write("extend enum ");
295        f.write(&self.name);
296        format_directives(&self.directives, f);
297        if !self.values.is_empty() {
298            f.write(" ");
299            f.start_block();
300            for val in &self.values {
301                f.indent();
302                if let Some(ref descr) = val.description {
303                    f.write_quoted(descr);
304                    f.write(" ");
305                }
306                f.write(&val.name);
307                format_directives(&val.directives, f);
308                f.endline();
309            }
310            f.end_block();
311        } else {
312            f.endline();
313        }
314    }
315}
316
317fn format_inputs(fields: &[InputValue], f: &mut Formatter) {
318    if !fields.is_empty() {
319        f.write(" ");
320        f.start_block();
321        for fld in fields {
322            f.indent();
323            fld.display(f);
324            f.endline();
325        }
326        f.end_block();
327    } else {
328        f.endline();
329    }
330}
331
332impl Displayable for InputObjectType {
333    fn display(&self, f: &mut Formatter) {
334        description(&self.description, f);
335        f.indent();
336        f.write("input ");
337        f.write(&self.name);
338        format_directives(&self.directives, f);
339        format_inputs(&self.fields, f);
340    }
341}
342
343impl Displayable for InputObjectTypeExtension {
344    fn display(&self, f: &mut Formatter) {
345        f.indent();
346        f.write("extend input ");
347        f.write(&self.name);
348        format_directives(&self.directives, f);
349        format_inputs(&self.fields, f);
350    }
351}
352
353impl Displayable for TypeExtension {
354    fn display(&self, f: &mut Formatter) {
355        match *self {
356            TypeExtension::Scalar(ref s) => s.display(f),
357            TypeExtension::Object(ref o) => o.display(f),
358            TypeExtension::Interface(ref i) => i.display(f),
359            TypeExtension::Union(ref u) => u.display(f),
360            TypeExtension::Enum(ref e) => e.display(f),
361            TypeExtension::InputObject(ref i) => i.display(f),
362        }
363    }
364}
365
366impl Displayable for DirectiveDefinition {
367    fn display(&self, f: &mut Formatter) {
368        description(&self.description, f);
369        f.indent();
370        f.write("directive @");
371        f.write(&self.name);
372        format_arguments(&self.arguments, f);
373        if self.repeatable {
374            f.write(" repeatable");
375        }
376        if !self.locations.is_empty() {
377            f.write(" on ");
378            let mut first = true;
379            for loc in &self.locations {
380                if first {
381                    first = false;
382                } else {
383                    f.write(" | ");
384                }
385                f.write(loc.as_str());
386            }
387        }
388        f.endline();
389    }
390}
391
392impl_display!(
393    Document,
394    Definition,
395    SchemaDefinition,
396    TypeDefinition,
397    TypeExtension,
398    ScalarType,
399    ScalarTypeExtension,
400    ObjectType,
401    ObjectTypeExtension,
402    Field,
403    InputValue,
404    InterfaceType,
405    InterfaceTypeExtension,
406    UnionType,
407    UnionTypeExtension,
408    EnumType,
409    EnumTypeExtension,
410    InputObjectType,
411    InputObjectTypeExtension,
412    DirectiveDefinition,
413);