gurkle_parser/query/
format.rs

1use std::fmt;
2
3use crate::format::{format_directives, Displayable, Formatter, Style};
4
5use crate::query::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
23impl Displayable for Document {
24    fn display(&self, f: &mut Formatter) {
25        for item in &self.definitions {
26            item.display(f);
27        }
28    }
29}
30
31impl Displayable for Definition {
32    fn display(&self, f: &mut Formatter) {
33        match *self {
34            Definition::Operation(ref op) => op.display(f),
35            Definition::Fragment(ref frag) => frag.display(f),
36        }
37    }
38}
39
40impl Displayable for OperationDefinition {
41    fn display(&self, f: &mut Formatter) {
42        match *self {
43            OperationDefinition::SelectionSet(ref set) => set.display(f),
44            OperationDefinition::Query(ref q) => q.display(f),
45            OperationDefinition::Mutation(ref m) => m.display(f),
46            OperationDefinition::Subscription(ref s) => s.display(f),
47        }
48    }
49}
50
51impl Displayable for FragmentDefinition {
52    fn display(&self, f: &mut Formatter) {
53        f.margin();
54        f.indent();
55        f.write("fragment ");
56        f.write(&self.name);
57        f.write(" ");
58        self.type_condition.display(f);
59        format_directives(&self.directives, f);
60        f.write(" ");
61        f.start_block();
62        for item in &self.selection_set.items {
63            item.display(f);
64        }
65        f.end_block();
66    }
67}
68
69impl Displayable for SelectionSet {
70    fn display(&self, f: &mut Formatter) {
71        f.margin();
72        f.indent();
73        f.start_block();
74        for item in &self.items {
75            item.display(f);
76        }
77        f.end_block();
78    }
79}
80
81impl Displayable for Selection {
82    fn display(&self, f: &mut Formatter) {
83        match *self {
84            Selection::Field(ref fld) => fld.display(f),
85            Selection::InlineFragment(ref frag) => frag.display(f),
86            Selection::FragmentSpread(ref frag) => frag.display(f),
87        }
88    }
89}
90
91fn format_arguments(arguments: &[(String, Value)], f: &mut Formatter) {
92    if !arguments.is_empty() {
93        f.write("(");
94        f.write(&arguments[0].0);
95        f.write(": ");
96        arguments[0].1.display(f);
97        for arg in &arguments[1..] {
98            f.write(", ");
99            f.write(&arg.0);
100            f.write(": ");
101            arg.1.display(f);
102        }
103        f.write(")");
104    }
105}
106
107impl Displayable for Field {
108    fn display(&self, f: &mut Formatter) {
109        f.indent();
110        if let Some(ref alias) = self.alias {
111            f.write(alias);
112            f.write(": ");
113        }
114        f.write(&self.name);
115        format_arguments(&self.arguments, f);
116        format_directives(&self.directives, f);
117        if !self.selection_set.items.is_empty() {
118            f.write(" ");
119            f.start_block();
120            for item in &self.selection_set.items {
121                item.display(f);
122            }
123            f.end_block();
124        } else {
125            f.endline();
126        }
127    }
128}
129
130impl Displayable for Query {
131    fn display(&self, f: &mut Formatter) {
132        f.margin();
133        f.indent();
134        f.write("query");
135        if let Some(ref name) = self.name {
136            f.write(" ");
137            f.write(name);
138            if !self.variable_definitions.is_empty() {
139                f.write("(");
140                self.variable_definitions[0].display(f);
141                for var in &self.variable_definitions[1..] {
142                    f.write(", ");
143                    var.display(f);
144                }
145                f.write(")");
146            }
147        }
148        format_directives(&self.directives, f);
149        f.write(" ");
150        f.start_block();
151        for item in &self.selection_set.items {
152            item.display(f);
153        }
154        f.end_block();
155    }
156}
157
158impl Displayable for Mutation {
159    fn display(&self, f: &mut Formatter) {
160        f.margin();
161        f.indent();
162        f.write("mutation");
163        if let Some(ref name) = self.name {
164            f.write(" ");
165            f.write(name);
166            if !self.variable_definitions.is_empty() {
167                f.write("(");
168                self.variable_definitions[0].display(f);
169                for var in &self.variable_definitions[1..] {
170                    f.write(", ");
171                    var.display(f);
172                }
173                f.write(")");
174            }
175        }
176        format_directives(&self.directives, f);
177        f.write(" ");
178        f.start_block();
179        for item in &self.selection_set.items {
180            item.display(f);
181        }
182        f.end_block();
183    }
184}
185
186impl Displayable for Subscription {
187    fn display(&self, f: &mut Formatter) {
188        f.margin();
189        f.indent();
190        f.write("subscription");
191        if let Some(ref name) = self.name {
192            f.write(" ");
193            f.write(name);
194            if !self.variable_definitions.is_empty() {
195                f.write("(");
196                self.variable_definitions[0].display(f);
197                for var in &self.variable_definitions[1..] {
198                    f.write(", ");
199                    var.display(f);
200                }
201                f.write(")");
202            }
203        }
204        format_directives(&self.directives, f);
205        f.write(" ");
206        f.start_block();
207        for item in &self.selection_set.items {
208            item.display(f);
209        }
210        f.end_block();
211    }
212}
213
214impl Displayable for VariableDefinition {
215    fn display(&self, f: &mut Formatter) {
216        f.write("$");
217        f.write(&self.name);
218        f.write(": ");
219        self.var_type.display(f);
220        if let Some(ref default) = self.default_value {
221            f.write(" = ");
222            default.display(f);
223        }
224    }
225}
226
227impl Displayable for Type {
228    fn display(&self, f: &mut Formatter) {
229        match *self {
230            Type::NamedType(ref name) => f.write(name),
231            Type::ListType(ref typ) => {
232                f.write("[");
233                typ.display(f);
234                f.write("]");
235            }
236            Type::NonNullType(ref typ) => {
237                typ.display(f);
238                f.write("!");
239            }
240        }
241    }
242}
243
244impl Displayable for Value {
245    fn display(&self, f: &mut Formatter) {
246        match *self {
247            Value::Variable(ref name) => {
248                f.write("$");
249                f.write(name);
250            }
251            Value::Int(ref num) => f.write(&format!("{}", num.0)),
252            Value::Float(val) => f.write(&format!("{}", val)),
253            Value::String(ref val) => f.write_quoted(val),
254            Value::Boolean(true) => f.write("true"),
255            Value::Boolean(false) => f.write("false"),
256            Value::Null => f.write("null"),
257            Value::Enum(ref name) => f.write(name),
258            Value::List(ref items) => {
259                f.write("[");
260                if !items.is_empty() {
261                    items[0].display(f);
262                    for item in &items[1..] {
263                        f.write(", ");
264                        item.display(f);
265                    }
266                }
267                f.write("]");
268            }
269            Value::Object(ref items) => {
270                f.write("{");
271                let mut first = true;
272                for (name, value) in items.iter() {
273                    if first {
274                        first = false;
275                    } else {
276                        f.write(", ");
277                    }
278                    f.write(name);
279                    f.write(": ");
280                    value.display(f);
281                }
282                f.write("}");
283            }
284        }
285    }
286}
287
288impl Displayable for InlineFragment {
289    fn display(&self, f: &mut Formatter) {
290        f.indent();
291        f.write("...");
292        if let Some(ref cond) = self.type_condition {
293            f.write(" ");
294            cond.display(f);
295        }
296        format_directives(&self.directives, f);
297        f.write(" ");
298        f.start_block();
299        for item in &self.selection_set.items {
300            item.display(f);
301        }
302        f.end_block();
303    }
304}
305
306impl Displayable for TypeCondition {
307    fn display(&self, f: &mut Formatter) {
308        match *self {
309            TypeCondition::On(ref name) => {
310                f.write("on ");
311                f.write(name);
312            }
313        }
314    }
315}
316
317impl Displayable for FragmentSpread {
318    fn display(&self, f: &mut Formatter) {
319        f.indent();
320        f.write("...");
321        f.write(&self.fragment_name);
322        format_directives(&self.directives, f);
323        f.endline();
324    }
325}
326
327impl Displayable for Directive {
328    fn display(&self, f: &mut Formatter) {
329        f.write("@");
330        f.write(&self.name);
331        format_arguments(&self.arguments, f);
332    }
333}
334
335impl_display!(
336    Document,
337    Definition,
338    OperationDefinition,
339    FragmentDefinition,
340    SelectionSet,
341    Field,
342    Query,
343    Mutation,
344    Subscription,
345    VariableDefinition,
346    Type,
347    Value,
348    InlineFragment,
349    TypeCondition,
350    FragmentSpread,
351    Directive,
352);