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 if let Some((first, rest)) = locations.split_first() {
268 state.write(" on ")?;
269 state.write(first.name())?;
270 for location in rest {
271 state.write(" | ")?;
272 state.write(location.name())?;
273 }
274 }
275 Ok(())
276 }
277}
278
279fn serialize_arguments_definition(
280 state: &mut State,
281 arguments: &[Node<InputValueDefinition>],
282) -> fmt::Result {
283 if !arguments.is_empty() {
284 let serialize_arguments = |state: &mut State| {
285 comma_separated(state, "(", ")", arguments, |state, arg| {
286 arg.serialize_impl(state)
287 })
288 };
289 if arguments
290 .iter()
291 .any(|arg| arg.description.is_some() || !arg.directives.is_empty())
292 {
293 serialize_arguments(state)?
294 } else {
295 state.on_single_line(serialize_arguments)?
296 }
297 }
298 Ok(())
299}
300
301impl SchemaDefinition {
302 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
303 let Self {
304 description,
305 directives,
306 root_operations,
307 } = self;
308 serialize_description(state, description)?;
309 state.write("schema")?;
310 directives.serialize_impl(state)?;
311 state.write(" ")?;
312 curly_brackets_space_separated(state, root_operations, |state, op| {
313 let (operation_type, operation_name) = &**op;
314 display!(state, "{}: {}", operation_type, operation_name)
315 })
316 }
317}
318
319impl ScalarTypeDefinition {
320 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
321 let Self {
322 description,
323 name,
324 directives,
325 } = self;
326 serialize_description(state, description)?;
327 state.write("scalar ")?;
328 state.write(name)?;
329 directives.serialize_impl(state)
330 }
331}
332
333impl ObjectTypeDefinition {
334 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
335 let Self {
336 description,
337 name,
338 implements_interfaces,
339 directives,
340 fields,
341 } = self;
342 serialize_description(state, description)?;
343 state.write("type ")?;
344 serialize_object_type_like(state, name, implements_interfaces, directives, fields)
345 }
346}
347
348fn serialize_object_type_like(
349 state: &mut State,
350 name: &str,
351 implements_interfaces: &[Name],
352 directives: &DirectiveList,
353 fields: &[Node<FieldDefinition>],
354) -> Result<(), fmt::Error> {
355 state.write(name)?;
356 if let Some((first, rest)) = implements_interfaces.split_first() {
357 state.write(" implements ")?;
358 state.write(first)?;
359 for name in rest {
360 state.write(" & ")?;
361 state.write(name)?;
362 }
363 }
364 directives.serialize_impl(state)?;
365
366 if !fields.is_empty() {
367 state.write(" ")?;
368 curly_brackets_space_separated(state, fields, |state, field| field.serialize_impl(state))?;
369 }
370 Ok(())
371}
372
373impl InterfaceTypeDefinition {
374 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
375 let Self {
376 description,
377 name,
378 implements_interfaces,
379 directives,
380 fields,
381 } = self;
382 serialize_description(state, description)?;
383 state.write("interface ")?;
384 serialize_object_type_like(state, name, implements_interfaces, directives, fields)
385 }
386}
387
388impl UnionTypeDefinition {
389 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
390 let Self {
391 description,
392 name,
393 directives,
394 members,
395 } = self;
396 serialize_description(state, description)?;
397 state.write("union ")?;
398 serialize_union(state, name, directives, members)
399 }
400}
401
402fn serialize_union(
403 state: &mut State,
404 name: &str,
405 directives: &DirectiveList,
406 members: &[Name],
407) -> fmt::Result {
408 state.write(name)?;
409 directives.serialize_impl(state)?;
410 if let Some((first, rest)) = members.split_first() {
411 state.write(" = ")?;
412 state.write(first)?;
413 for member in rest {
414 state.write(" | ")?;
415 state.write(member)?;
416 }
417 }
418 Ok(())
419}
420
421impl EnumTypeDefinition {
422 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
423 let Self {
424 description,
425 name,
426 directives,
427 values,
428 } = self;
429 serialize_description(state, description)?;
430 state.write("enum ")?;
431 state.write(name)?;
432 directives.serialize_impl(state)?;
433 if !values.is_empty() {
434 state.write(" ")?;
435 curly_brackets_space_separated(state, values, |state, value| {
436 value.serialize_impl(state)
437 })?;
438 }
439 Ok(())
440 }
441}
442
443impl InputObjectTypeDefinition {
444 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
445 let Self {
446 description,
447 name,
448 directives,
449 fields,
450 } = self;
451 serialize_description(state, description)?;
452 state.write("input ")?;
453 state.write(name)?;
454 directives.serialize_impl(state)?;
455 if !fields.is_empty() {
456 state.write(" ")?;
457 curly_brackets_space_separated(state, fields, |state, f| f.serialize_impl(state))?;
458 }
459 Ok(())
460 }
461}
462
463impl SchemaExtension {
464 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
465 let Self {
466 directives,
467 root_operations,
468 } = self;
469 state.write("extend schema")?;
470 directives.serialize_impl(state)?;
471 if !root_operations.is_empty() {
472 state.write(" ")?;
473 curly_brackets_space_separated(state, root_operations, |state, op| {
474 let (operation_type, operation_name) = &**op;
475 display!(state, "{}: {}", operation_type, operation_name)
476 })?;
477 }
478 Ok(())
479 }
480}
481
482impl ScalarTypeExtension {
483 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
484 let Self { name, directives } = self;
485 state.write("extend scalar ")?;
486 state.write(name)?;
487 directives.serialize_impl(state)
488 }
489}
490
491impl ObjectTypeExtension {
492 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
493 let Self {
494 name,
495 implements_interfaces,
496 directives,
497 fields,
498 } = self;
499 state.write("extend type ")?;
500 serialize_object_type_like(state, name, implements_interfaces, directives, fields)
501 }
502}
503
504impl InterfaceTypeExtension {
505 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
506 let Self {
507 name,
508 implements_interfaces,
509 directives,
510 fields,
511 } = self;
512 state.write("extend interface ")?;
513 serialize_object_type_like(state, name, implements_interfaces, directives, fields)
514 }
515}
516
517impl UnionTypeExtension {
518 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
519 let Self {
520 name,
521 directives,
522 members,
523 } = self;
524 state.write("extend union ")?;
525 serialize_union(state, name, directives, members)
526 }
527}
528
529impl EnumTypeExtension {
530 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
531 let Self {
532 name,
533 directives,
534 values,
535 } = self;
536 state.write("extend enum ")?;
537 state.write(name)?;
538 directives.serialize_impl(state)?;
539 if !values.is_empty() {
540 state.write(" ")?;
541 curly_brackets_space_separated(state, values, |state, value| {
542 value.serialize_impl(state)
543 })?;
544 }
545 Ok(())
546 }
547}
548
549impl InputObjectTypeExtension {
550 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
551 let Self {
552 name,
553 directives,
554 fields,
555 } = self;
556 state.write("extend input ")?;
557 state.write(name)?;
558 directives.serialize_impl(state)?;
559 if !fields.is_empty() {
560 state.write(" ")?;
561 curly_brackets_space_separated(state, fields, |state, f| f.serialize_impl(state))?;
562 }
563 Ok(())
564 }
565}
566
567impl DirectiveList {
568 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
569 for dir in self {
570 state.write(" ")?;
571 dir.serialize_impl(state)?;
572 }
573 Ok(())
574 }
575}
576
577impl Directive {
578 pub(crate) fn serialize_impl(&self, state: &mut State) -> fmt::Result {
579 let Self { name, arguments } = self;
580 state.write("@")?;
581 state.write(name)?;
582 serialize_arguments(state, arguments)
583 }
584}
585
586impl VariableDefinition {
587 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
588 let Self {
589 description,
590 name,
591 ty,
592 default_value,
593 directives,
594 } = self;
595 serialize_description(state, description)?;
596 state.write("$")?;
597 state.write(name)?;
598 state.write(": ")?;
599 display!(state, ty)?;
600 if let Some(value) = default_value {
601 state.write(" = ")?;
602 value.serialize_impl(state)?
603 }
604 directives.serialize_impl(state)
605 }
606}
607
608impl FieldDefinition {
609 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
610 let Self {
611 description,
612 name,
613 arguments,
614 ty,
615 directives,
616 } = self;
617 serialize_description(state, description)?;
618 state.write(name)?;
619 serialize_arguments_definition(state, arguments)?;
620 state.write(": ")?;
621 display!(state, ty)?;
622 directives.serialize_impl(state)
623 }
624}
625
626impl InputValueDefinition {
627 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
628 let Self {
629 description,
630 name,
631 ty,
632 default_value,
633 directives,
634 } = self;
635 serialize_description(state, description)?;
636 state.write(name)?;
637 state.write(": ")?;
638 display!(state, ty)?;
639 if let Some(value) = default_value {
640 state.write(" = ")?;
641 value.serialize_impl(state)?
642 }
643 directives.serialize_impl(state)
644 }
645}
646
647impl EnumValueDefinition {
648 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
649 let Self {
650 description,
651 value,
652 directives,
653 } = self;
654 serialize_description(state, description)?;
655 state.write(value)?;
656 directives.serialize_impl(state)
657 }
658}
659
660impl Selection {
661 pub(crate) fn serialize_impl(&self, state: &mut State) -> fmt::Result {
662 match self {
663 Selection::Field(x) => x.serialize_impl(state),
664 Selection::FragmentSpread(x) => x.serialize_impl(state),
665 Selection::InlineFragment(x) => x.serialize_impl(state),
666 }
667 }
668}
669
670impl Field {
671 pub(crate) fn serialize_impl(&self, state: &mut State) -> fmt::Result {
672 let Self {
673 alias,
674 name,
675 arguments,
676 directives,
677 selection_set,
678 } = self;
679 if let Some(alias) = alias {
680 state.write(alias)?;
681 state.write(": ")?;
682 }
683 state.write(name)?;
684 serialize_arguments(state, arguments)?;
685 directives.serialize_impl(state)?;
686 if !selection_set.is_empty() {
687 state.write(" ")?;
688 curly_brackets_space_separated(state, selection_set, |state, sel| {
689 sel.serialize_impl(state)
690 })?
691 }
692 Ok(())
693 }
694}
695
696impl FragmentSpread {
697 pub(crate) fn serialize_impl(&self, state: &mut State) -> fmt::Result {
698 let Self {
699 fragment_name,
700 directives,
701 } = self;
702 state.write("...")?;
703 state.write(fragment_name)?;
704 directives.serialize_impl(state)
705 }
706}
707
708impl InlineFragment {
709 pub(crate) fn serialize_impl(&self, state: &mut State) -> fmt::Result {
710 let Self {
711 type_condition,
712 directives,
713 selection_set,
714 } = self;
715 if let Some(type_name) = type_condition {
716 state.write("... on ")?;
717 state.write(type_name)?;
718 } else {
719 state.write("...")?;
720 }
721 directives.serialize_impl(state)?;
722 state.write(" ")?;
723 curly_brackets_space_separated(state, selection_set, |state, sel| sel.serialize_impl(state))
724 }
725}
726
727impl Value {
728 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
729 match self {
730 Value::Null => state.write("null"),
731 Value::Boolean(true) => state.write("true"),
732 Value::Boolean(false) => state.write("false"),
733 Value::Enum(name) => state.write(name),
734 Value::String(value) => {
735 let is_description = false;
736 serialize_string_value(state, is_description, value)
737 }
738 Value::Variable(name) => display!(state, "${}", name),
739 Value::Float(value) => display!(state, value),
740 Value::Int(value) => display!(state, value),
741 Value::List(value) => comma_separated(state, "[", "]", value, |state, value| {
742 value.serialize_impl(state)
743 }),
744 Value::Object(value) => {
745 comma_separated(state, "{", "}", value, |state, (name, value)| {
746 state.write(name)?;
747 state.write(": ")?;
748 value.serialize_impl(state)
749 })
750 }
751 }
752 }
753}
754
755impl Argument {
756 fn serialize_impl(&self, state: &mut State) -> fmt::Result {
757 state.write(&self.name)?;
758 state.write(": ")?;
759 self.value.serialize_impl(state)
760 }
761}
762
763fn serialize_arguments(state: &mut State, arguments: &[Node<Argument>]) -> fmt::Result {
764 if !arguments.is_empty() {
765 state.on_single_line(|state| {
766 comma_separated(state, "(", ")", arguments, |state, argument| {
767 argument.serialize_impl(state)
768 })
769 })?
770 }
771 Ok(())
772}
773
774fn comma_separated<T>(
784 state: &mut State,
785 open: &str,
786 close: &str,
787 values: &[T],
788 serialize_one: impl Fn(&mut State, &T) -> fmt::Result,
789) -> fmt::Result {
790 state.write(open)?;
791 if let Some((first, rest)) = values.split_first() {
792 state.indent()?;
793 serialize_one(state, first)?;
794 for value in rest {
795 state.write(",")?;
796 state.new_line_or_space()?;
797 serialize_one(state, value)?;
798 }
799 if state.newlines_enabled() {
801 state.write(",")?;
802 }
803 state.dedent()?;
804 }
805 state.write(close)
806}
807
808pub(crate) fn curly_brackets_space_separated<T>(
818 state: &mut State,
819 values: &[T],
820 serialize_one: impl Fn(&mut State, &T) -> fmt::Result,
821) -> fmt::Result {
822 state.write("{")?;
823 if let Some((first, rest)) = values.split_first() {
824 state.indent_or_space()?;
825 serialize_one(state, first)?;
826 for value in rest {
827 state.new_line_or_space()?;
828 serialize_one(state, value)?;
829 }
830 state.dedent_or_space()?;
831 }
832 state.write("}")
833}
834
835fn serialize_string_value(state: &mut State, is_description: bool, mut str: &str) -> fmt::Result {
836 let contains_newline = str.contains('\n');
837 let prefer_block_string = is_description || contains_newline;
838 if state.newlines_enabled() && prefer_block_string && can_be_block_string(str) {
839 return serialize_block_string(state, contains_newline, str);
840 }
841 state.write("\"")?;
842 loop {
843 if let Some(i) = str.find(|c| (c < ' ' && c != '\t') || c == '"' || c == '\\') {
844 let (without_escaping, rest) = str.split_at(i);
845 state.write(without_escaping)?;
846 match rest.as_bytes()[0] {
849 b'\x08' => state.write("\\b")?,
850 b'\n' => state.write("\\n")?,
851 b'\x0C' => state.write("\\f")?,
852 b'\r' => state.write("\\r")?,
853 b'"' => state.write("\\\"")?,
854 b'\\' => state.write("\\\\")?,
855 byte => display!(state, "\\u{:04X}", byte)?,
856 }
857 str = &rest[1..]
858 } else {
859 state.write(str)?;
860 break;
861 }
862 }
863 state.write("\"")
864}
865
866fn serialize_block_string(state: &mut State, contains_newline: bool, str: &str) -> fmt::Result {
867 const TRIPLE_QUOTE: &str = "\"\"\"";
868 const ESCAPED_TRIPLE_QUOTE: &str = "\\\"\"\"";
869 const _: () = assert!(TRIPLE_QUOTE.len() == 3);
870 const _: () = assert!(ESCAPED_TRIPLE_QUOTE.len() == 4);
871
872 fn serialize_line(state: &mut State, mut line: &str) -> Result<(), fmt::Error> {
873 while let Some((before, after)) = line.split_once(TRIPLE_QUOTE) {
874 state.write(before)?;
875 state.write(ESCAPED_TRIPLE_QUOTE)?;
876 line = after;
877 }
878 state.write(line)
879 }
880
881 let multi_line =
882 contains_newline || str.len() > 70 || str.ends_with('"') || str.ends_with('\\');
883
884 state.write(TRIPLE_QUOTE)?;
885 if !multi_line {
886 serialize_line(state, str)?
888 } else {
889 for line in str.split('\n') {
895 if line.is_empty() {
896 state.write("\n")?;
898 } else {
899 state.require_new_line()?;
900 serialize_line(state, line)?;
901 }
902 }
903 state.require_new_line()?;
904 }
905 state.write(TRIPLE_QUOTE)
906}
907
908fn can_be_block_string(value: &str) -> bool {
912 if value.contains('\r') {
915 return false;
916 }
917
918 fn trim_start_graphql_whitespace(value: &str) -> &str {
920 value.trim_start_matches([' ', '\t'])
921 }
922
923 let mut lines = value.split('\n');
925 if lines
926 .next()
927 .is_some_and(|first| trim_start_graphql_whitespace(first).is_empty())
928 || lines
929 .next_back()
930 .is_some_and(|last| trim_start_graphql_whitespace(last).is_empty())
931 {
932 return false;
934 }
935
936 let common_indent = {
937 let lines = value.split('\n');
938 let each_line_indent_utf8_len = lines.filter_map(|line| {
939 let after_indent = trim_start_graphql_whitespace(line);
940 if !after_indent.is_empty() {
941 Some(line.len() - after_indent.len())
942 } else {
943 None }
945 });
946 each_line_indent_utf8_len.min().unwrap_or(0)
947 };
948 common_indent == 0
951}
952
953fn serialize_description(state: &mut State, description: &Option<Node<str>>) -> fmt::Result {
954 if let Some(description) = description {
955 let is_description = true;
956 serialize_string_value(state, is_description, description)?;
957 state.new_line_or_space()?;
958 }
959 Ok(())
960}
961
962impl fmt::Display for Type {
963 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
964 match self {
965 Type::Named(name) => std::write!(f, "{name}"),
966 Type::NonNullNamed(name) => std::write!(f, "{name}!"),
967 Type::List(inner) => std::write!(f, "[{inner}]"),
968 Type::NonNullList(inner) => std::write!(f, "[{inner}]!"),
969 }
970 }
971}
972
973impl fmt::Display for OperationType {
974 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
975 self.name().fmt(f)
976 }
977}
978
979impl fmt::Display for DirectiveLocation {
980 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
981 self.name().fmt(f)
982 }
983}
984
985macro_rules! impl_display {
986 ($($ty: path)+) => {
987 $(
988 impl Display for $ty {
990 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
991 self.serialize().fmt(f)
992 }
993 }
994
995 impl Display for Serialize<'_, $ty> {
997 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
998 let mut state = State {
999 config: self.config.clone(),
1000 indent_level: self.config.initial_indent_level,
1001 output: f,
1002 output_empty: true,
1003 };
1004 if let Some(prefix) = state.config.indent_prefix {
1007 for _ in 0..state.indent_level {
1008 state.write(prefix)?;
1009 }
1010 }
1011 self.node.serialize_impl(&mut state)
1012 }
1013 }
1014 )+
1015 }
1016}
1017
1018impl_display! {
1019 Document
1020 Definition
1021 OperationDefinition
1022 FragmentDefinition
1023 DirectiveDefinition
1024 SchemaDefinition
1025 ScalarTypeDefinition
1026 ObjectTypeDefinition
1027 InterfaceTypeDefinition
1028 UnionTypeDefinition
1029 EnumTypeDefinition
1030 InputObjectTypeDefinition
1031 SchemaExtension
1032 ScalarTypeExtension
1033 ObjectTypeExtension
1034 InterfaceTypeExtension
1035 UnionTypeExtension
1036 EnumTypeExtension
1037 InputObjectTypeExtension
1038 DirectiveList
1039 Directive
1040 VariableDefinition
1041 FieldDefinition
1042 InputValueDefinition
1043 EnumValueDefinition
1044 Selection
1045 Field
1046 FragmentSpread
1047 InlineFragment
1048 Value
1049 crate::Schema
1050 crate::ExecutableDocument
1051 schema::DirectiveList
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}