graphql_tools/parser/query/
format.rs1use std::fmt;
2
3use crate::parser::format::{format_directives, Displayable, Formatter, Style};
4
5use super::ast::*;
6
7impl<'a, T: Text<'a>> Document<'a, T> {
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
23impl<'a, T: Text<'a>> Displayable for Document<'a, T> {
24 fn display(&self, f: &mut Formatter) {
25 for item in &self.definitions {
26 item.display(f);
27 }
28 }
29}
30
31impl<'a, T: Text<'a>> Displayable for Definition<'a, T> {
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<'a, T: Text<'a>> Displayable for OperationDefinition<'a, T> {
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<'a, T: Text<'a>> Displayable for FragmentDefinition<'a, T> {
52 fn display(&self, f: &mut Formatter) {
53 f.margin();
54 f.indent();
55 f.write("fragment ");
56 f.write(self.name.as_ref());
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<'a, T: Text<'a>> Displayable for SelectionSet<'a, T> {
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<'a, T: Text<'a>> Displayable for Selection<'a, T> {
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<'a, T: Text<'a>>(arguments: &[(T::Value, Value<'a, T>)], f: &mut Formatter) {
92 if !arguments.is_empty() {
93 f.start_argument_block('(');
94 f.start_argument();
95 f.write(arguments[0].0.as_ref());
96 f.write(": ");
97 arguments[0].1.display(f);
98 for arg in &arguments[1..] {
99 f.deliniate_argument();
100 f.start_argument();
101 f.write(arg.0.as_ref());
102 f.write(": ");
103 arg.1.display(f);
104 }
105 f.end_argument_block(')');
106 }
107}
108
109impl<'a, T: Text<'a>> Displayable for Field<'a, T> {
110 fn display(&self, f: &mut Formatter) {
111 f.indent();
112 if let Some(ref alias) = self.alias {
113 f.write(alias.as_ref());
114 f.write(": ");
115 }
116 f.write(self.name.as_ref());
117 format_arguments(&self.arguments, f);
118 format_directives(&self.directives, f);
119 if !self.selection_set.items.is_empty() {
120 f.write(" ");
121 f.start_block();
122 for item in &self.selection_set.items {
123 item.display(f);
124 }
125 f.end_block();
126 } else {
127 f.endline();
128 }
129 }
130}
131
132impl<'a, T: Text<'a>> Displayable for Query<'a, T> {
133 fn display(&self, f: &mut Formatter) {
134 f.margin();
135 f.indent();
136 f.write("query");
137 if let Some(ref name) = self.name {
138 f.write(" ");
139 f.write(name.as_ref());
140 }
141 if !self.variable_definitions.is_empty() {
142 f.write("(");
143 self.variable_definitions[0].display(f);
144 for var in &self.variable_definitions[1..] {
145 f.write(", ");
146 var.display(f);
147 }
148 f.write(")");
149 }
150 format_directives(&self.directives, f);
151 f.write(" ");
152 f.start_block();
153 for item in &self.selection_set.items {
154 item.display(f);
155 }
156 f.end_block();
157 }
158}
159
160impl<'a, T: Text<'a>> Displayable for Mutation<'a, T> {
161 fn display(&self, f: &mut Formatter) {
162 f.margin();
163 f.indent();
164 f.write("mutation");
165 if let Some(ref name) = self.name {
166 f.write(" ");
167 f.write(name.as_ref());
168 }
169 if !self.variable_definitions.is_empty() {
170 f.write("(");
171 self.variable_definitions[0].display(f);
172 for var in &self.variable_definitions[1..] {
173 f.write(", ");
174 var.display(f);
175 }
176 f.write(")");
177 }
178 format_directives(&self.directives, f);
179 f.write(" ");
180 f.start_block();
181 for item in &self.selection_set.items {
182 item.display(f);
183 }
184 f.end_block();
185 }
186}
187
188impl<'a, T: Text<'a>> Displayable for Subscription<'a, T> {
189 fn display(&self, f: &mut Formatter) {
190 f.margin();
191 f.indent();
192 f.write("subscription");
193 if let Some(ref name) = self.name {
194 f.write(" ");
195 f.write(name.as_ref());
196 if !self.variable_definitions.is_empty() {
197 f.write("(");
198 for var in &self.variable_definitions {
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<'a, T: Text<'a>> Displayable for VariableDefinition<'a, T> {
215 fn display(&self, f: &mut Formatter) {
216 f.write("$");
217 f.write(self.name.as_ref());
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<'a, T: Text<'a>> Displayable for Type<'a, T> {
228 fn display(&self, f: &mut Formatter) {
229 match *self {
230 Type::NamedType(ref name) => f.write(name.as_ref()),
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<'a, T: Text<'a>> Displayable for Value<'a, T> {
245 fn display(&self, f: &mut Formatter) {
246 match *self {
247 Value::Variable(ref name) => {
248 f.write("$");
249 f.write(name.as_ref());
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.as_ref()),
258 Value::List(ref items) => {
259 f.start_argument_block('[');
260 if !items.is_empty() {
261 f.start_argument();
262 items[0].display(f);
263 for item in &items[1..] {
264 f.deliniate_argument();
265 f.start_argument();
266 item.display(f);
267 }
268 }
269 f.end_argument_block(']');
270 }
271 Value::Object(ref items) => {
272 f.start_argument_block('{');
273 let mut first = true;
274 for (name, value) in items.iter() {
275 if first {
276 first = false;
277 } else {
278 f.deliniate_argument();
279 }
280 f.start_argument();
281 f.write(name.as_ref());
282 f.write(": ");
283 value.display(f);
284 }
285 f.end_argument_block('}');
286 }
287 }
288 }
289}
290
291impl<'a, T: Text<'a>> Displayable for InlineFragment<'a, T> {
292 fn display(&self, f: &mut Formatter) {
293 f.indent();
294 f.write("...");
295 if let Some(ref cond) = self.type_condition {
296 f.write(" ");
297 cond.display(f);
298 }
299 format_directives(&self.directives, f);
300 f.write(" ");
301 f.start_block();
302 for item in &self.selection_set.items {
303 item.display(f);
304 }
305 f.end_block();
306 }
307}
308
309impl<'a, T: Text<'a>> Displayable for TypeCondition<'a, T> {
310 fn display(&self, f: &mut Formatter) {
311 match *self {
312 TypeCondition::On(ref name) => {
313 f.write("on ");
314 f.write(name.as_ref());
315 }
316 }
317 }
318}
319
320impl<'a, T: Text<'a>> Displayable for FragmentSpread<'a, T> {
321 fn display(&self, f: &mut Formatter) {
322 f.indent();
323 f.write("...");
324 f.write(self.fragment_name.as_ref());
325 format_directives(&self.directives, f);
326 f.endline();
327 }
328}
329
330impl<'a, T: Text<'a>> Displayable for Directive<'a, T> {
331 fn display(&self, f: &mut Formatter) {
332 f.write("@");
333 f.write(self.name.as_ref());
334 format_arguments(self.arguments.as_slice(), f);
335 }
336}
337
338impl_display!(
339 'a
340 Document,
341 Definition,
342 OperationDefinition,
343 FragmentDefinition,
344 SelectionSet,
345 Field,
346 Query,
347 Mutation,
348 Subscription,
349 VariableDefinition,
350 Type,
351 Value,
352 InlineFragment,
353 TypeCondition,
354 FragmentSpread,
355 Directive,
356);