1use std::fmt;
2
3use crate::format::{format_directives, Displayable, Formatter, Style};
4
5use crate::schema::ast::*;
6
7impl Document {
8 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);