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