1use super::*;
2use crate::executable;
3use crate::schema;
4use std::fmt;
5use std::fmt::Display;
6
7#[derive(Debug, Clone)]
10pub struct Serialize<'a, T> {
11 pub(crate) node: &'a T,
12 pub(crate) config: Config<'a>,
13}
14
15#[derive(Debug, Clone)]
16pub(crate) struct Config<'a> {
17 indent_prefix: Option<&'a str>,
18 initial_indent_level: usize,
19}
20
21pub(crate) struct State<'config, 'fmt, 'fmt2> {
22 config: Config<'config>,
23 indent_level: usize,
24 output: &'fmt mut fmt::Formatter<'fmt2>,
25 output_empty: bool,
27}
28
29impl<'a, T> Serialize<'a, T> {
30 pub fn indent_prefix(mut self, prefix: &'a str) -> Self {
35 self.config.indent_prefix = Some(prefix);
36 self
37 }
38
39 pub fn no_indent(mut self) -> Self {
41 self.config.indent_prefix = None;
42 self
43 }
44
45 pub fn initial_indent_level(mut self, initial_indent_level: usize) -> Self {
46 self.config.initial_indent_level = initial_indent_level;
47 self
48 }
49}
50
51impl Default for Config<'_> {
52 fn default() -> Self {
53 Self {
54 indent_prefix: Some(" "),
55 initial_indent_level: 0,
56 }
57 }
58}
59
60macro_rules! display {
61 ($state: expr, $e: expr) => {
62 fmt::Display::fmt(&$e, $state.output)
63 };
64 ($state: expr, $($tt: tt)+) => {
65 display!($state, format_args!($($tt)+))
66 };
67
68}
69
70impl State<'_, '_, '_> {
71 pub(crate) fn write(&mut self, str: &str) -> fmt::Result {
72 self.output_empty = false;
73 self.output.write_str(str)
74 }
75
76 pub(crate) fn indent(&mut self) -> fmt::Result {
77 self.indent_level += 1;
78 self.new_line_common(false)
79 }
80
81 pub(crate) fn indent_or_space(&mut self) -> fmt::Result {
82 self.indent_level += 1;
83 self.new_line_common(true)
84 }
85
86 pub(crate) fn dedent(&mut self) -> fmt::Result {
87 self.indent_level -= 1; self.new_line_common(false)
89 }
90
91 pub(crate) fn dedent_or_space(&mut self) -> fmt::Result {
92 self.indent_level -= 1; self.new_line_common(true)
94 }
95
96 pub(crate) fn new_line_or_space(&mut self) -> fmt::Result {
97 self.new_line_common(true)
98 }
99
100 fn new_line_common(&mut self, space: bool) -> fmt::Result {
101 if let Some(prefix) = self.config.indent_prefix {
102 self.write("\n")?;
103 for _ in 0..self.indent_level {
104 self.write(prefix)?;
105 }
106 } else if space {
107 self.write(" ")?
108 }
109 Ok(())
110 }
111
112 fn require_new_line(&mut self) -> fmt::Result {
114 let prefix = self
115 .config
116 .indent_prefix
117 .expect("require_new_line called with newlines disabled");
118 self.write("\n")?;
119 for _ in 0..self.indent_level {
120 self.write(prefix)?;
121 }
122 Ok(())
123 }
124
125 pub(crate) fn newlines_enabled(&self) -> bool {
126 self.config.indent_prefix.is_some()
127 }
128
129 pub(crate) fn on_single_line<R>(&mut self, f: impl FnOnce(&mut Self) -> R) -> R {
130 let indent_prefix = self.config.indent_prefix.take();
131 let result = f(self);
132 self.config.indent_prefix = indent_prefix;
133 result
134 }
135}
136
137impl Document {
138 pub(crate) fn serialize_impl(&self, state: &mut State) -> fmt::Result {
139 top_level(state, &self.definitions, |state, def| {
140 def.serialize_impl(state)
141 })
142 }
143}
144
145pub(crate) fn top_level<T>(
146 state: &mut State,
147 iter: impl IntoIterator<Item = T>,
148 serialize_one: impl Fn(&mut State, T) -> fmt::Result,
149) -> fmt::Result {
150 let mut iter = iter.into_iter();
151 if let Some(first) = iter.next() {
152 serialize_one(state, first)?;
153 iter.try_for_each(|item| {
154 if state.newlines_enabled() {
155 state.write("\n")?;
157 }
158 state.new_line_or_space()?;
159 serialize_one(state, item)
160 })?;
161 if state.newlines_enabled() {
163 state.write("\n")?;
164 }
165 }
166 Ok(())
167}
168
169impl Definition {
170 pub(crate) fn serialize_impl(&self, state: &mut State) -> fmt::Result {
171 match self {
172 Definition::OperationDefinition(def) => def.serialize_impl(state),
173 Definition::FragmentDefinition(def) => def.serialize_impl(state),
174 Definition::DirectiveDefinition(def) => def.serialize_impl(state),
175 Definition::SchemaDefinition(def) => def.serialize_impl(state),
176 Definition::ScalarTypeDefinition(def) => def.serialize_impl(state),
177 Definition::ObjectTypeDefinition(def) => def.serialize_impl(state),
178 Definition::InterfaceTypeDefinition(def) => def.serialize_impl(state),
179 Definition::UnionTypeDefinition(def) => def.serialize_impl(state),
180 Definition::EnumTypeDefinition(def) => def.serialize_impl(state),
181 Definition::InputObjectTypeDefinition(def) => def.serialize_impl(state),
182 Definition::SchemaExtension(def) => def.serialize_impl(state),
183 Definition::ScalarTypeExtension(def) => def.serialize_impl(state),
184 Definition::ObjectTypeExtension(def) => def.serialize_impl(state),
185 Definition::InterfaceTypeExtension(def) => def.serialize_impl(state),
186 Definition::UnionTypeExtension(def) => def.serialize_impl(state),
187 Definition::EnumTypeExtension(def) => def.serialize_impl(state),
188 Definition::InputObjectTypeExtension(def) => def.serialize_impl(state),
189 }
190 }
191}
192
193impl OperationDefinition {
194 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
195 let Self {
197 description,
198 operation_type,
199 name,
200 variables,
201 directives,
202 selection_set,
203 } = self;
204 let shorthand = state.output_empty
207 && description.is_none()
208 && *operation_type == OperationType::Query
209 && name.is_none()
210 && variables.is_empty()
211 && directives.is_empty();
212 if !shorthand {
213 serialize_description(state, description)?;
214 state.write(operation_type.name())?;
215 if let Some(name) = &name {
216 state.write(" ")?;
217 state.write(name)?;
218 }
219 if !variables.is_empty() {
220 state.on_single_line(|state| {
221 comma_separated(state, "(", ")", variables, |state, var| {
222 var.serialize_impl(state)
223 })
224 })?
225 }
226 directives.serialize_impl(state)?;
227 state.write(" ")?;
228 }
229 curly_brackets_space_separated(state, selection_set, |state, sel| sel.serialize_impl(state))
230 }
231}
232
233impl FragmentDefinition {
234 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
235 let Self {
236 description,
237 name,
238 type_condition,
239 directives,
240 selection_set,
241 } = self;
242 serialize_description(state, description)?;
243 display!(state, "fragment {} on {}", name, type_condition)?;
244 directives.serialize_impl(state)?;
245 state.write(" ")?;
246 curly_brackets_space_separated(state, selection_set, |state, sel| sel.serialize_impl(state))
247 }
248}
249
250impl DirectiveDefinition {
251 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
252 let Self {
253 description,
254 name,
255 arguments,
256 repeatable,
257 locations,
258 } = self;
259 serialize_description(state, description)?;
260 state.write("directive @")?;
261 state.write(name)?;
262 serialize_arguments_definition(state, arguments)?;
263
264 if *repeatable {
265 state.write(" repeatable")?;
266 }
267 let mut loc_iter = locations.iter();
268 if let Some(first) = loc_iter.next() {
269 state.write(" on ")?;
270 state.write(first.name())?;
271 for location in loc_iter {
272 state.write(" | ")?;
273 state.write(location.name())?;
274 }
275 }
276 Ok(())
277 }
278}
279
280fn serialize_arguments_definition(
281 state: &mut State,
282 arguments: &[Node<InputValueDefinition>],
283) -> fmt::Result {
284 if !arguments.is_empty() {
285 let serialize_arguments = |state: &mut State| {
286 comma_separated(state, "(", ")", arguments, |state, arg| {
287 arg.serialize_impl(state)
288 })
289 };
290 if arguments
291 .iter()
292 .any(|arg| arg.description.is_some() || !arg.directives.is_empty())
293 {
294 serialize_arguments(state)?
295 } else {
296 state.on_single_line(serialize_arguments)?
297 }
298 }
299 Ok(())
300}
301
302impl SchemaDefinition {
303 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
304 let Self {
305 description,
306 directives,
307 root_operations,
308 } = self;
309 serialize_description(state, description)?;
310 state.write("schema")?;
311 directives.serialize_impl(state)?;
312 state.write(" ")?;
313 curly_brackets_space_separated(state, root_operations, |state, op| {
314 let (operation_type, operation_name) = &**op;
315 display!(state, "{}: {}", operation_type, operation_name)
316 })
317 }
318}
319
320impl ScalarTypeDefinition {
321 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
322 let Self {
323 description,
324 name,
325 directives,
326 } = self;
327 serialize_description(state, description)?;
328 state.write("scalar ")?;
329 state.write(name)?;
330 directives.serialize_impl(state)
331 }
332}
333
334impl ObjectTypeDefinition {
335 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
336 let Self {
337 description,
338 name,
339 implements_interfaces,
340 directives,
341 fields,
342 } = self;
343 serialize_description(state, description)?;
344 state.write("type ")?;
345 serialize_object_type_like(state, name, implements_interfaces, directives, fields)
346 }
347}
348
349fn serialize_object_type_like(
350 state: &mut State,
351 name: &str,
352 implements_interfaces: &[Name],
353 directives: &DirectiveList,
354 fields: &[Node<FieldDefinition>],
355) -> Result<(), fmt::Error> {
356 state.write(name)?;
357 if let Some((first, rest)) = implements_interfaces.split_first() {
358 state.write(" implements ")?;
359 state.write(first)?;
360 for name in rest {
361 state.write(" & ")?;
362 state.write(name)?;
363 }
364 }
365 directives.serialize_impl(state)?;
366
367 if !fields.is_empty() {
368 state.write(" ")?;
369 curly_brackets_space_separated(state, fields, |state, field| field.serialize_impl(state))?;
370 }
371 Ok(())
372}
373
374impl InterfaceTypeDefinition {
375 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
376 let Self {
377 description,
378 name,
379 implements_interfaces,
380 directives,
381 fields,
382 } = self;
383 serialize_description(state, description)?;
384 state.write("interface ")?;
385 serialize_object_type_like(state, name, implements_interfaces, directives, fields)
386 }
387}
388
389impl UnionTypeDefinition {
390 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
391 let Self {
392 description,
393 name,
394 directives,
395 members,
396 } = self;
397 serialize_description(state, description)?;
398 state.write("union ")?;
399 serialize_union(state, name, directives, members)
400 }
401}
402
403fn serialize_union(
404 state: &mut State,
405 name: &str,
406 directives: &DirectiveList,
407 members: &[Name],
408) -> fmt::Result {
409 state.write(name)?;
410 directives.serialize_impl(state)?;
411 if let Some((first, rest)) = members.split_first() {
412 state.write(" = ")?;
413 state.write(first)?;
414 for member in rest {
415 state.write(" | ")?;
416 state.write(member)?;
417 }
418 }
419 Ok(())
420}
421
422impl EnumTypeDefinition {
423 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
424 let Self {
425 description,
426 name,
427 directives,
428 values,
429 } = self;
430 serialize_description(state, description)?;
431 state.write("enum ")?;
432 state.write(name)?;
433 directives.serialize_impl(state)?;
434 if !values.is_empty() {
435 state.write(" ")?;
436 curly_brackets_space_separated(state, values, |state, value| {
437 value.serialize_impl(state)
438 })?;
439 }
440 Ok(())
441 }
442}
443
444impl InputObjectTypeDefinition {
445 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
446 let Self {
447 description,
448 name,
449 directives,
450 fields,
451 } = self;
452 serialize_description(state, description)?;
453 state.write("input ")?;
454 state.write(name)?;
455 directives.serialize_impl(state)?;
456 if !fields.is_empty() {
457 state.write(" ")?;
458 curly_brackets_space_separated(state, fields, |state, f| f.serialize_impl(state))?;
459 }
460 Ok(())
461 }
462}
463
464impl SchemaExtension {
465 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
466 let Self {
467 directives,
468 root_operations,
469 } = self;
470 state.write("extend schema")?;
471 directives.serialize_impl(state)?;
472 if !root_operations.is_empty() {
473 state.write(" ")?;
474 curly_brackets_space_separated(state, root_operations, |state, op| {
475 let (operation_type, operation_name) = &**op;
476 display!(state, "{}: {}", operation_type, operation_name)
477 })?;
478 }
479 Ok(())
480 }
481}
482
483impl ScalarTypeExtension {
484 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
485 let Self { name, directives } = self;
486 state.write("extend scalar ")?;
487 state.write(name)?;
488 directives.serialize_impl(state)
489 }
490}
491
492impl ObjectTypeExtension {
493 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
494 let Self {
495 name,
496 implements_interfaces,
497 directives,
498 fields,
499 } = self;
500 state.write("extend type ")?;
501 serialize_object_type_like(state, name, implements_interfaces, directives, fields)
502 }
503}
504
505impl InterfaceTypeExtension {
506 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
507 let Self {
508 name,
509 implements_interfaces,
510 directives,
511 fields,
512 } = self;
513 state.write("extend interface ")?;
514 serialize_object_type_like(state, name, implements_interfaces, directives, fields)
515 }
516}
517
518impl UnionTypeExtension {
519 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
520 let Self {
521 name,
522 directives,
523 members,
524 } = self;
525 state.write("extend union ")?;
526 serialize_union(state, name, directives, members)
527 }
528}
529
530impl EnumTypeExtension {
531 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
532 let Self {
533 name,
534 directives,
535 values,
536 } = self;
537 state.write("extend enum ")?;
538 state.write(name)?;
539 directives.serialize_impl(state)?;
540 if !values.is_empty() {
541 state.write(" ")?;
542 curly_brackets_space_separated(state, values, |state, value| {
543 value.serialize_impl(state)
544 })?;
545 }
546 Ok(())
547 }
548}
549
550impl InputObjectTypeExtension {
551 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
552 let Self {
553 name,
554 directives,
555 fields,
556 } = self;
557 state.write("extend input ")?;
558 state.write(name)?;
559 directives.serialize_impl(state)?;
560 if !fields.is_empty() {
561 state.write(" ")?;
562 curly_brackets_space_separated(state, fields, |state, f| f.serialize_impl(state))?;
563 }
564 Ok(())
565 }
566}
567
568impl DirectiveList {
569 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
570 for dir in self {
571 state.write(" ")?;
572 dir.serialize_impl(state)?;
573 }
574 Ok(())
575 }
576}
577
578impl Directive {
579 pub(crate) fn serialize_impl(&self, state: &mut State) -> fmt::Result {
580 let Self { name, arguments } = self;
581 state.write("@")?;
582 state.write(name)?;
583 serialize_arguments(state, arguments)
584 }
585}
586
587impl VariableDefinition {
588 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
589 let Self {
590 description,
591 name,
592 ty,
593 default_value,
594 directives,
595 } = self;
596 serialize_description(state, description)?;
597 state.write("$")?;
598 state.write(name)?;
599 state.write(": ")?;
600 display!(state, ty)?;
601 if let Some(value) = default_value {
602 state.write(" = ")?;
603 value.serialize_impl(state)?
604 }
605 directives.serialize_impl(state)
606 }
607}
608
609impl FieldDefinition {
610 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
611 let Self {
612 description,
613 name,
614 arguments,
615 ty,
616 directives,
617 } = self;
618 serialize_description(state, description)?;
619 state.write(name)?;
620 serialize_arguments_definition(state, arguments)?;
621 state.write(": ")?;
622 display!(state, ty)?;
623 directives.serialize_impl(state)
624 }
625}
626
627impl InputValueDefinition {
628 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
629 let Self {
630 description,
631 name,
632 ty,
633 default_value,
634 directives,
635 } = self;
636 serialize_description(state, description)?;
637 state.write(name)?;
638 state.write(": ")?;
639 display!(state, ty)?;
640 if let Some(value) = default_value {
641 state.write(" = ")?;
642 value.serialize_impl(state)?
643 }
644 directives.serialize_impl(state)
645 }
646}
647
648impl EnumValueDefinition {
649 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
650 let Self {
651 description,
652 value,
653 directives,
654 } = self;
655 serialize_description(state, description)?;
656 state.write(value)?;
657 directives.serialize_impl(state)
658 }
659}
660
661impl Selection {
662 pub(crate) fn serialize_impl(&self, state: &mut State) -> fmt::Result {
663 match self {
664 Selection::Field(x) => x.serialize_impl(state),
665 Selection::FragmentSpread(x) => x.serialize_impl(state),
666 Selection::InlineFragment(x) => x.serialize_impl(state),
667 }
668 }
669}
670
671impl Field {
672 pub(crate) fn serialize_impl(&self, state: &mut State) -> fmt::Result {
673 let Self {
674 alias,
675 name,
676 arguments,
677 directives,
678 selection_set,
679 } = self;
680 if let Some(alias) = alias {
681 state.write(alias)?;
682 state.write(": ")?;
683 }
684 state.write(name)?;
685 serialize_arguments(state, arguments)?;
686 directives.serialize_impl(state)?;
687 if !selection_set.is_empty() {
688 state.write(" ")?;
689 curly_brackets_space_separated(state, selection_set, |state, sel| {
690 sel.serialize_impl(state)
691 })?
692 }
693 Ok(())
694 }
695}
696
697impl FragmentSpread {
698 pub(crate) fn serialize_impl(&self, state: &mut State) -> fmt::Result {
699 let Self {
700 fragment_name,
701 directives,
702 } = self;
703 state.write("...")?;
704 state.write(fragment_name)?;
705 directives.serialize_impl(state)
706 }
707}
708
709impl InlineFragment {
710 pub(crate) fn serialize_impl(&self, state: &mut State) -> fmt::Result {
711 let Self {
712 type_condition,
713 directives,
714 selection_set,
715 } = self;
716 if let Some(type_name) = type_condition {
717 state.write("... on ")?;
718 state.write(type_name)?;
719 } else {
720 state.write("...")?;
721 }
722 directives.serialize_impl(state)?;
723 state.write(" ")?;
724 curly_brackets_space_separated(state, selection_set, |state, sel| sel.serialize_impl(state))
725 }
726}
727
728impl Value {
729 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
730 match self {
731 Value::Null => state.write("null"),
732 Value::Boolean(true) => state.write("true"),
733 Value::Boolean(false) => state.write("false"),
734 Value::Enum(name) => state.write(name),
735 Value::String(value) => {
736 let is_description = false;
737 serialize_string_value(state, is_description, value)
738 }
739 Value::Variable(name) => display!(state, "${}", name),
740 Value::Float(value) => display!(state, value),
741 Value::Int(value) => display!(state, value),
742 Value::List(value) => comma_separated(state, "[", "]", value, |state, value| {
743 value.serialize_impl(state)
744 }),
745 Value::Object(value) => {
746 comma_separated(state, "{", "}", value, |state, (name, value)| {
747 state.write(name)?;
748 state.write(": ")?;
749 value.serialize_impl(state)
750 })
751 }
752 }
753 }
754}
755
756impl Argument {
757 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
758 state.write(&self.name)?;
759 state.write(": ")?;
760 self.value.serialize_impl(state)
761 }
762}
763
764fn serialize_arguments(state: &mut State, arguments: &[Node<Argument>]) -> fmt::Result {
765 if !arguments.is_empty() {
766 state.on_single_line(|state| {
767 comma_separated(state, "(", ")", arguments, |state, argument| {
768 argument.serialize_impl(state)
769 })
770 })?
771 }
772 Ok(())
773}
774
775fn comma_separated<T>(
785 state: &mut State,
786 open: &str,
787 close: &str,
788 values: &[T],
789 serialize_one: impl Fn(&mut State, &T) -> fmt::Result,
790) -> fmt::Result {
791 state.write(open)?;
792 if let Some((first, rest)) = values.split_first() {
793 state.indent()?;
794 serialize_one(state, first)?;
795 for value in rest {
796 state.write(",")?;
797 state.new_line_or_space()?;
798 serialize_one(state, value)?;
799 }
800 if state.newlines_enabled() {
802 state.write(",")?;
803 }
804 state.dedent()?;
805 }
806 state.write(close)
807}
808
809pub(crate) fn curly_brackets_space_separated<T>(
819 state: &mut State,
820 values: &[T],
821 serialize_one: impl Fn(&mut State, &T) -> fmt::Result,
822) -> fmt::Result {
823 state.write("{")?;
824 if let Some((first, rest)) = values.split_first() {
825 state.indent_or_space()?;
826 serialize_one(state, first)?;
827 for value in rest {
828 state.new_line_or_space()?;
829 serialize_one(state, value)?;
830 }
831 state.dedent_or_space()?;
832 }
833 state.write("}")
834}
835
836fn serialize_string_value(state: &mut State, is_description: bool, mut str: &str) -> fmt::Result {
837 let contains_newline = str.contains('\n');
838 let prefer_block_string = is_description || contains_newline;
839 if state.newlines_enabled() && prefer_block_string && can_be_block_string(str) {
840 return serialize_block_string(state, contains_newline, str);
841 }
842 state.write("\"")?;
843 loop {
844 if let Some(i) = str.find(|c| (c < ' ' && c != '\t') || c == '"' || c == '\\') {
845 let (without_escaping, rest) = str.split_at(i);
846 state.write(without_escaping)?;
847 match rest.as_bytes()[0] {
850 b'\x08' => state.write("\\b")?,
851 b'\n' => state.write("\\n")?,
852 b'\x0C' => state.write("\\f")?,
853 b'\r' => state.write("\\r")?,
854 b'"' => state.write("\\\"")?,
855 b'\\' => state.write("\\\\")?,
856 byte => display!(state, "\\u{:04X}", byte)?,
857 }
858 str = &rest[1..]
859 } else {
860 state.write(str)?;
861 break;
862 }
863 }
864 state.write("\"")
865}
866
867fn serialize_block_string(state: &mut State, contains_newline: bool, str: &str) -> fmt::Result {
868 const TRIPLE_QUOTE: &str = "\"\"\"";
869 const ESCAPED_TRIPLE_QUOTE: &str = "\\\"\"\"";
870 const _: () = assert!(TRIPLE_QUOTE.len() == 3);
871 const _: () = assert!(ESCAPED_TRIPLE_QUOTE.len() == 4);
872
873 fn serialize_line(state: &mut State, mut line: &str) -> Result<(), fmt::Error> {
874 while let Some((before, after)) = line.split_once(TRIPLE_QUOTE) {
875 state.write(before)?;
876 state.write(ESCAPED_TRIPLE_QUOTE)?;
877 line = after;
878 }
879 state.write(line)
880 }
881
882 let multi_line =
883 contains_newline || str.len() > 70 || str.ends_with('"') || str.ends_with('\\');
884
885 state.write(TRIPLE_QUOTE)?;
886 if !multi_line {
887 serialize_line(state, str)?
889 } else {
890 for line in str.split('\n') {
896 if line.is_empty() {
897 state.write("\n")?;
899 } else {
900 state.require_new_line()?;
901 serialize_line(state, line)?;
902 }
903 }
904 state.require_new_line()?;
905 }
906 state.write(TRIPLE_QUOTE)
907}
908
909fn can_be_block_string(value: &str) -> bool {
913 if value.contains('\r') {
916 return false;
917 }
918
919 fn trim_start_graphql_whitespace(value: &str) -> &str {
921 value.trim_start_matches([' ', '\t'])
922 }
923
924 let mut lines = value.split('\n');
926 if lines
927 .next()
928 .is_some_and(|first| trim_start_graphql_whitespace(first).is_empty())
929 || lines
930 .next_back()
931 .is_some_and(|last| trim_start_graphql_whitespace(last).is_empty())
932 {
933 return false;
935 }
936
937 let common_indent = {
938 let lines = value.split('\n');
939 let each_line_indent_utf8_len = lines.filter_map(|line| {
940 let after_indent = trim_start_graphql_whitespace(line);
941 if !after_indent.is_empty() {
942 Some(line.len() - after_indent.len())
943 } else {
944 None }
946 });
947 each_line_indent_utf8_len.min().unwrap_or(0)
948 };
949 common_indent == 0
952}
953
954fn serialize_description(state: &mut State, description: &Option<Node<str>>) -> fmt::Result {
955 if let Some(description) = description {
956 let is_description = true;
957 serialize_string_value(state, is_description, description)?;
958 state.new_line_or_space()?;
959 }
960 Ok(())
961}
962
963impl fmt::Display for Type {
964 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
965 match self {
966 Type::Named(name) => std::write!(f, "{name}"),
967 Type::NonNullNamed(name) => std::write!(f, "{name}!"),
968 Type::List(inner) => std::write!(f, "[{inner}]"),
969 Type::NonNullList(inner) => std::write!(f, "[{inner}]!"),
970 }
971 }
972}
973
974impl fmt::Display for OperationType {
975 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
976 self.name().fmt(f)
977 }
978}
979
980impl fmt::Display for DirectiveLocation {
981 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
982 self.name().fmt(f)
983 }
984}
985
986macro_rules! impl_display {
987 ($($ty: path)+) => {
988 $(
989 impl Display for $ty {
991 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
992 self.serialize().fmt(f)
993 }
994 }
995
996 impl Display for Serialize<'_, $ty> {
998 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
999 let mut state = State {
1000 config: self.config.clone(),
1001 indent_level: self.config.initial_indent_level,
1002 output: f,
1003 output_empty: true,
1004 };
1005 if let Some(prefix) = state.config.indent_prefix {
1008 for _ in 0..state.indent_level {
1009 state.write(prefix)?;
1010 }
1011 }
1012 self.node.serialize_impl(&mut state)
1013 }
1014 }
1015 )+
1016 }
1017}
1018
1019impl_display! {
1020 Document
1021 Definition
1022 OperationDefinition
1023 FragmentDefinition
1024 DirectiveDefinition
1025 SchemaDefinition
1026 ScalarTypeDefinition
1027 ObjectTypeDefinition
1028 InterfaceTypeDefinition
1029 UnionTypeDefinition
1030 EnumTypeDefinition
1031 InputObjectTypeDefinition
1032 SchemaExtension
1033 ScalarTypeExtension
1034 ObjectTypeExtension
1035 InterfaceTypeExtension
1036 UnionTypeExtension
1037 EnumTypeExtension
1038 InputObjectTypeExtension
1039 DirectiveList
1040 Directive
1041 VariableDefinition
1042 FieldDefinition
1043 InputValueDefinition
1044 EnumValueDefinition
1045 Selection
1046 Field
1047 FragmentSpread
1048 InlineFragment
1049 Value
1050 crate::Schema
1051 crate::ExecutableDocument
1052 schema::ExtendedType
1053 schema::ScalarType
1054 schema::ObjectType
1055 schema::InterfaceType
1056 schema::EnumType
1057 schema::UnionType
1058 schema::InputObjectType
1059 executable::Operation
1060 executable::Fragment
1061 executable::SelectionSet
1062 executable::Selection
1063 executable::Field
1064 executable::InlineFragment
1065 executable::FragmentSpread
1066 executable::FieldSet
1067}