1use std::io;
2
3use graphql_toolkit_ast::{
4 indexmap::IndexMap, BaseType, ConstValue, Directive, DocumentOperations, ExecutableDocument,
5 Field, FragmentDefinition, FragmentSpread, InlineFragment, Name, Number, OperationDefinition,
6 OperationType, Positioned, Selection, SelectionSet, Type, TypeCondition, Value,
7 VariableDefinition,
8};
9
10use crate::fmt::formatter::Formatter;
11
12pub trait Serialize {
14 fn serialize<W, F>(&self, ser: &mut Serializer<W, F>) -> anyhow::Result<()>
16 where
17 W: io::Write,
18 F: Formatter;
19}
20
21pub struct Serializer<W, F> {
23 writer: W,
24 formatter: F,
25}
26
27impl<W, F> Serializer<W, F>
28where
29 W: io::Write,
30 F: Formatter,
31{
32 #[inline]
34 pub fn with_formatter(writer: W, formatter: F) -> Self {
35 Self { writer, formatter }
36 }
37}
38
39impl<W, F> Serializer<W, F>
40where
41 W: io::Write,
42 F: Formatter,
43{
44 fn serialize_executable_document(&mut self, value: &ExecutableDocument) -> anyhow::Result<()> {
45 match &value.operations {
46 DocumentOperations::Single(def) => {
47 self.serialize_operation_definition(&def.node, None, true)?;
48 }
49 DocumentOperations::Multiple(def) => {
50 let mut first_operation = true;
51 for (name, def) in def.iter() {
52 if !first_operation {
53 self.formatter
54 .before_operation_or_fragment_definition(&mut self.writer)?;
55 }
56
57 self.serialize_operation_definition(&def.node, Some(name), false)?;
58 first_operation = false;
59 }
60 }
61 }
62
63 for (name, fragment) in value.fragments.iter() {
64 self.formatter
65 .before_operation_or_fragment_definition(&mut self.writer)?;
66 self.serialize_fragment_definition(name, &fragment.node)?;
67 }
68
69 Ok(())
70 }
71
72 fn serialize_operation_definition(
73 &mut self,
74 value: &OperationDefinition,
75 name: Option<&Name>,
76 single: bool,
77 ) -> anyhow::Result<()> {
78 let shorthand = single
87 && value.ty == OperationType::Query
88 && name.is_none()
89 && value.variable_definitions.is_empty()
90 && value.directives.is_empty();
91
92 if !shorthand {
94 match value.ty {
96 OperationType::Query => {
97 self.formatter.write_keyword(&mut self.writer, "query")?;
98 }
99 OperationType::Mutation => {
100 self.formatter.write_keyword(&mut self.writer, "mutation")?;
101 }
102 OperationType::Subscription => {
103 self.formatter
104 .write_keyword(&mut self.writer, "subscription")?;
105 }
106 }
107
108 if let Some(name) = name {
110 self.formatter.write_separator(&mut self.writer)?;
111 name.serialize(self)?;
112 }
113
114 if name.is_none() && !value.variable_definitions.is_empty() {
116 self.formatter
117 .before_operation_variable_definitions(&mut self.writer)?;
118 }
119 if !value.variable_definitions.is_empty() {
120 self.formatter.begin_parentheses(&mut self.writer)?;
121
122 let mut iter = value.variable_definitions.iter().peekable();
123 while let Some(def) = iter.next() {
124 def.serialize(self)?;
125
126 if iter.peek().is_some() {
128 self.formatter.write_item_separator(&mut self.writer)?;
129 }
130 }
131
132 self.formatter.end_parentheses(&mut self.writer)?;
133 }
134
135 for directive in value.directives.iter() {
137 directive.serialize(self)?;
138 }
139
140 self.formatter
141 .after_operation_or_fragment_signature(&mut self.writer)?;
142 }
143
144 value.selection_set.serialize(self)?;
146
147 Ok(())
148 }
149
150 fn serialize_selection_set(&mut self, value: &SelectionSet) -> anyhow::Result<()> {
151 if value.items.is_empty() {
153 return Ok(());
154 }
155
156 self.formatter.begin_block(&mut self.writer)?;
157
158 let mut iter = value.items.iter().peekable();
159 while let Some(selection) = iter.next() {
160 self.formatter.before_block_item(&mut self.writer)?;
161 selection.serialize(self)?;
162
163 if iter.peek().is_some() {
165 self.formatter.after_block_item(&mut self.writer)?;
166 }
167 }
168
169 self.formatter.end_block(&mut self.writer)?;
170
171 Ok(())
172 }
173
174 fn serialize_selection(&mut self, value: &Selection) -> anyhow::Result<()> {
175 match value {
176 Selection::Field(field) => field.serialize(self),
177 Selection::FragmentSpread(fragment) => fragment.serialize(self),
178 Selection::InlineFragment(fragment) => fragment.serialize(self),
179 }?;
180
181 Ok(())
182 }
183
184 fn serialize_selection_field(&mut self, value: &Field) -> anyhow::Result<()> {
185 if let Some(alias) = &value.alias {
186 alias.serialize(self)?;
187 self.formatter
188 .write_name_value_separator(&mut self.writer)?;
189 }
190
191 value.name.serialize(self)?;
192
193 if !value.arguments.is_empty() {
194 self.serialize_arguments(&value.arguments)?;
195 }
196
197 for directive in value.directives.iter() {
198 directive.serialize(self)?;
199 }
200
201 if !value.selection_set.node.items.is_empty() {
202 self.formatter.after_selection_signature(&mut self.writer)?;
203 }
204 value.selection_set.serialize(self)?;
205
206 Ok(())
207 }
208
209 fn serialize_fragment_spread(&mut self, value: &FragmentSpread) -> anyhow::Result<()> {
210 self.formatter.write_keyword(&mut self.writer, "...")?;
211 value.fragment_name.serialize(self)?;
212
213 for directive in value.directives.iter() {
214 directive.serialize(self)?;
215 }
216
217 Ok(())
218 }
219
220 fn serialize_inline_fragment(&mut self, value: &InlineFragment) -> anyhow::Result<()> {
221 self.formatter.write_keyword(&mut self.writer, "...")?;
222
223 if let Some(type_condition) = &value.type_condition {
224 self.formatter.before_type_condition(&mut self.writer)?;
225 type_condition.serialize(self)?;
226 }
227
228 for directive in value.directives.iter() {
229 directive.serialize(self)?;
230 }
231
232 if !value.selection_set.node.items.is_empty() {
233 self.formatter.after_selection_signature(&mut self.writer)?;
234 }
235 value.selection_set.serialize(self)?;
236
237 Ok(())
238 }
239
240 fn serialize_arguments(
241 &mut self,
242 value: &[(Positioned<Name>, Positioned<Value>)],
243 ) -> anyhow::Result<()> {
244 self.formatter.begin_parentheses(&mut self.writer)?;
245
246 let mut iter = value.iter().peekable();
247 while let Some((name, value)) = iter.next() {
248 name.serialize(self)?;
249 self.formatter
250 .write_name_value_separator(&mut self.writer)?;
251 value.serialize(self)?;
252
253 if iter.peek().is_some() {
255 self.formatter.write_item_separator(&mut self.writer)?;
256 }
257 }
258
259 self.formatter.end_parentheses(&mut self.writer)?;
260
261 Ok(())
262 }
263
264 fn serialize_directive(&mut self, value: &Directive) -> anyhow::Result<()> {
265 self.formatter.before_directive(&mut self.writer)?;
266
267 self.formatter.begin_directive(&mut self.writer)?;
269 value.name.serialize(self)?;
270
271 if !value.arguments.is_empty() {
273 self.serialize_arguments(&value.arguments)?;
274 }
275
276 Ok(())
277 }
278
279 fn serialize_variable_definition(&mut self, value: &VariableDefinition) -> anyhow::Result<()> {
280 self.formatter.begin_variable(&mut self.writer)?;
282 value.name.serialize(self)?;
283
284 self.formatter
286 .write_name_value_separator(&mut self.writer)?;
287
288 value.var_type.serialize(self)?;
290
291 if let Some(default_value) = &value.default_value {
292 self.formatter
293 .write_variable_default_value_separator(&mut self.writer)?;
294 default_value.serialize(self)?;
295 }
296
297 for directive in value.directives.iter() {
298 directive.serialize(self)?;
299 }
300
301 Ok(())
302 }
303
304 fn serialize_type(&mut self, value: &Type) -> anyhow::Result<()> {
305 match &value.base {
306 BaseType::Named(name) => {
307 name.serialize(self)?;
308 }
309 BaseType::List(list) => {
310 self.formatter.begin_array(&mut self.writer)?;
311 list.serialize(self)?;
312 self.formatter.end_array(&mut self.writer)?;
313 }
314 }
315
316 if !value.nullable {
317 self.formatter
318 .write_non_null_type_indicator(&mut self.writer)?;
319 }
320
321 Ok(())
322 }
323
324 fn serialize_fragment_definition(
325 &mut self,
326 name: &Name,
327 value: &FragmentDefinition,
328 ) -> anyhow::Result<()> {
329 self.formatter.write_keyword(&mut self.writer, "fragment")?;
330
331 self.formatter.write_separator(&mut self.writer)?;
332 name.serialize(self)?;
333 self.formatter.write_separator(&mut self.writer)?;
334
335 value.type_condition.serialize(self)?;
336
337 for directive in value.directives.iter() {
338 directive.serialize(self)?;
339 }
340
341 self.formatter
342 .after_operation_or_fragment_signature(&mut self.writer)?;
343
344 value.selection_set.serialize(self)?;
345
346 Ok(())
347 }
348
349 fn serialize_type_condition(&mut self, value: &TypeCondition) -> anyhow::Result<()> {
350 self.formatter.write_keyword(&mut self.writer, "on")?;
351 self.formatter.write_separator(&mut self.writer)?;
352 value.on.serialize(self)
353 }
354
355 fn serialize_name(&mut self, value: &Name) -> anyhow::Result<()> {
356 self.formatter
357 .write_string_fragment(&mut self.writer, value)?;
358
359 Ok(())
360 }
361
362 fn serialize_value(&mut self, value: &Value) -> anyhow::Result<()> {
363 match value {
364 Value::Null => {
365 self.formatter.write_null(&mut self.writer)?;
366 }
367 Value::Number(value) => {
368 value.serialize(self)?;
369 }
370 Value::String(value) => {
372 self.formatter.begin_string(&mut self.writer)?;
373 self.formatter
374 .write_string_fragment(&mut self.writer, value)?;
375 self.formatter.end_string(&mut self.writer)?;
376 }
377 Value::Boolean(value) => {
378 self.formatter.write_bool(&mut self.writer, *value)?;
379 }
380 Value::Variable(name) => {
381 self.formatter.begin_variable(&mut self.writer)?;
382 name.serialize(self)?;
383 }
384 Value::Enum(value) => {
385 value.serialize(self)?;
386 }
387 Value::List(list) => {
388 self.serialize_value_array(list)?;
389 }
390 Value::Object(value) => {
391 self.serialize_value_object(value)?;
392 }
393 Value::Binary(value) => {
394 self.formatter
395 .write_byte_array(&mut self.writer, &value[..])?;
396 }
397 }
398
399 Ok(())
400 }
401
402 fn serialize_value_array(&mut self, value: &[Value]) -> anyhow::Result<()> {
403 self.formatter.begin_array(&mut self.writer)?;
404
405 let mut iter = value.iter().peekable();
406 while let Some(value) = iter.next() {
407 value.serialize(self)?;
408
409 if iter.peek().is_some() {
411 self.formatter.write_item_separator(&mut self.writer)?;
412 }
413 }
414
415 self.formatter.end_array(&mut self.writer)?;
416
417 Ok(())
418 }
419
420 fn serialize_value_object(&mut self, value: &IndexMap<Name, Value>) -> anyhow::Result<()> {
421 self.formatter.begin_object(&mut self.writer)?;
422
423 let mut iter = value.iter().peekable();
424 while let Some((key, value)) = iter.next() {
425 key.serialize(self)?;
426 self.formatter
427 .write_name_value_separator(&mut self.writer)?;
428 value.serialize(self)?;
429
430 if iter.peek().is_some() {
432 self.formatter.write_item_separator(&mut self.writer)?;
433 }
434 }
435
436 self.formatter.end_object(&mut self.writer)?;
437
438 Ok(())
439 }
440
441 fn serialize_const_value(&mut self, value: &ConstValue) -> anyhow::Result<()> {
442 match value {
443 ConstValue::Null => {
444 self.formatter.write_null(&mut self.writer)?;
445 }
446 ConstValue::Number(value) => {
447 value.serialize(self)?;
448 }
449 ConstValue::String(value) => {
450 self.formatter.begin_string(&mut self.writer)?;
452 self.formatter
453 .write_string_fragment(&mut self.writer, value)?;
454 self.formatter.end_string(&mut self.writer)?;
455 }
456 ConstValue::Boolean(value) => {
457 self.formatter.write_bool(&mut self.writer, *value)?;
458 }
459 ConstValue::Enum(value) => {
460 value.serialize(self)?;
461 }
462 ConstValue::List(list) => {
463 self.serialize_const_value_array(list)?;
464 }
465 ConstValue::Object(object) => {
466 self.serialize_const_value_object(object)?;
467 }
468 ConstValue::Binary(value) => {
469 self.formatter
470 .write_byte_array(&mut self.writer, &value[..])?;
471 }
472 }
473
474 Ok(())
475 }
476
477 fn serialize_const_value_array(&mut self, value: &[ConstValue]) -> anyhow::Result<()> {
478 self.formatter.begin_array(&mut self.writer)?;
479
480 let mut iter = value.iter().peekable();
481 while let Some(value) = iter.next() {
482 value.serialize(self)?;
483
484 if iter.peek().is_some() {
486 self.formatter.write_item_separator(&mut self.writer)?;
487 }
488 }
489
490 self.formatter.end_array(&mut self.writer)?;
491
492 Ok(())
493 }
494
495 fn serialize_const_value_object(
496 &mut self,
497 value: &IndexMap<Name, ConstValue>,
498 ) -> anyhow::Result<()> {
499 self.formatter.begin_object(&mut self.writer)?;
500
501 let mut iter = value.iter().peekable();
502 while let Some((key, value)) = iter.next() {
503 key.serialize(self)?;
504 self.formatter
505 .write_name_value_separator(&mut self.writer)?;
506 value.serialize(self)?;
507
508 if iter.peek().is_some() {
510 self.formatter.write_item_separator(&mut self.writer)?;
511 }
512 }
513
514 self.formatter.end_object(&mut self.writer)?;
515
516 Ok(())
517 }
518
519 fn serialize_number(&mut self, value: &Number) -> anyhow::Result<()> {
520 if let Some(u) = value.as_u64() {
521 self.formatter.write_u64(&mut self.writer, u)?;
522 } else if let Some(i) = value.as_i64() {
523 self.formatter.write_i64(&mut self.writer, i)?;
524 } else if let Some(f) = value.as_f64() {
525 self.formatter.write_f64(&mut self.writer, f)?;
526 } else {
527 unreachable!("invalid number")
528 }
529
530 Ok(())
531 }
532}
533
534macro_rules! impl_serialize {
536 ($ty:ty, $method:ident) => {
537 impl Serialize for $ty {
538 #[inline]
539 fn serialize<W, F>(&self, ser: &mut Serializer<W, F>) -> anyhow::Result<()>
540 where
541 W: io::Write,
542 F: Formatter,
543 {
544 ser.$method(self)
545 }
546 }
547 };
548}
549
550impl<T> Serialize for Positioned<T>
551where
552 T: Serialize,
553{
554 #[inline]
555 fn serialize<W, F>(&self, ser: &mut Serializer<W, F>) -> anyhow::Result<()>
556 where
557 W: io::Write,
558 F: Formatter,
559 {
560 self.node.serialize(ser)
561 }
562}
563
564impl Serialize for OperationDefinition {
565 #[inline]
566 fn serialize<W, F>(&self, ser: &mut Serializer<W, F>) -> anyhow::Result<()>
567 where
568 W: io::Write,
569 F: Formatter,
570 {
571 ser.serialize_operation_definition(self, None, true)
574 }
575}
576
577impl Serialize for (Name, OperationDefinition) {
578 #[inline]
579 fn serialize<W, F>(&self, ser: &mut Serializer<W, F>) -> anyhow::Result<()>
580 where
581 W: io::Write,
582 F: Formatter,
583 {
584 let (name, operation) = self;
585 ser.serialize_operation_definition(operation, Some(name), true)
586 }
587}
588
589impl Serialize for (Name, FragmentDefinition) {
590 #[inline]
591 fn serialize<W, F>(&self, ser: &mut Serializer<W, F>) -> anyhow::Result<()>
592 where
593 W: io::Write,
594 F: Formatter,
595 {
596 let (name, fragment) = self;
597 ser.serialize_fragment_definition(name, fragment)
598 }
599}
600
601impl_serialize!(ExecutableDocument, serialize_executable_document);
602impl_serialize!(SelectionSet, serialize_selection_set);
603impl_serialize!(Selection, serialize_selection);
604impl_serialize!(Field, serialize_selection_field);
605impl_serialize!(FragmentSpread, serialize_fragment_spread);
606impl_serialize!(InlineFragment, serialize_inline_fragment);
607impl_serialize!(Directive, serialize_directive);
608impl_serialize!(VariableDefinition, serialize_variable_definition);
609impl_serialize!(Type, serialize_type);
610impl_serialize!(ConstValue, serialize_const_value);
611impl_serialize!(TypeCondition, serialize_type_condition);
612impl_serialize!(Name, serialize_name);
613impl_serialize!(Value, serialize_value);
614impl_serialize!(Number, serialize_number);