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