1use std::convert::TryFrom;
2
3use apollo_parser::cst::{self, CstNode};
4use thiserror::Error;
5
6#[derive(Debug, Clone, Error)]
12pub enum FromError {
13 #[error("parse tree is missing a node")]
15 MissingNode,
16 #[error("invalid i32")]
18 ParseIntError(#[from] std::num::ParseIntError),
19 #[error("invalid f64")]
21 ParseFloatError(#[from] std::num::ParseFloatError),
22}
23
24impl TryFrom<cst::Value> for crate::Value {
25 type Error = FromError;
26
27 fn try_from(node: cst::Value) -> Result<Self, Self::Error> {
34 let encoder_node = match node {
35 cst::Value::Variable(variable) => Self::Variable(
36 variable
37 .name()
38 .ok_or(FromError::MissingNode)?
39 .text()
40 .to_string(),
41 ),
42 cst::Value::StringValue(string) => Self::String(string.into()),
43 cst::Value::FloatValue(float) => Self::Float(
44 float
45 .float_token()
46 .ok_or(FromError::MissingNode)?
47 .text()
48 .parse()?,
49 ),
50 cst::Value::IntValue(int) => Self::Int(
51 int.int_token()
52 .ok_or(FromError::MissingNode)?
53 .text()
54 .parse()?,
55 ),
56 cst::Value::BooleanValue(boolean) => Self::Boolean(boolean.true_token().is_some()),
57 cst::Value::NullValue(_) => Self::Null,
58 cst::Value::EnumValue(enum_) => Self::Enum(enum_.text().to_string()),
59 cst::Value::ListValue(list) => {
60 let encoder_list = list
61 .values()
62 .map(Self::try_from)
63 .collect::<Result<Vec<_>, FromError>>()?;
64 Self::List(encoder_list)
65 }
66 cst::Value::ObjectValue(object) => {
67 let encoder_object = object
68 .object_fields()
69 .map(|field| {
70 let name = field
71 .name()
72 .ok_or(FromError::MissingNode)?
73 .text()
74 .to_string();
75 let value = field.value().ok_or(FromError::MissingNode)?.try_into()?;
76 Ok((name, value))
77 })
78 .collect::<Result<Vec<_>, FromError>>()?;
79 Self::Object(encoder_object)
80 }
81 };
82
83 Ok(encoder_node)
84 }
85}
86
87impl TryFrom<cst::DefaultValue> for crate::Value {
88 type Error = FromError;
89
90 fn try_from(node: cst::DefaultValue) -> Result<Self, Self::Error> {
97 node.value().ok_or(FromError::MissingNode)?.try_into()
98 }
99}
100
101impl TryFrom<cst::Directive> for crate::Directive {
102 type Error = FromError;
103
104 fn try_from(node: cst::Directive) -> Result<Self, Self::Error> {
111 let name = node
112 .name()
113 .ok_or(FromError::MissingNode)?
114 .text()
115 .to_string();
116 let mut directive = Self::new(name);
117
118 if let Some(arguments) = node.arguments() {
119 for argument in arguments.arguments() {
120 directive.arg(argument.try_into()?);
121 }
122 }
123
124 Ok(directive)
125 }
126}
127
128impl TryFrom<cst::Argument> for crate::Argument {
129 type Error = FromError;
130
131 fn try_from(node: cst::Argument) -> Result<Self, Self::Error> {
138 let name = node
139 .name()
140 .ok_or(FromError::MissingNode)?
141 .text()
142 .to_string();
143 let value = node.value().ok_or(FromError::MissingNode)?.try_into()?;
144 Ok(crate::Argument::new(name, value))
145 }
146}
147
148impl TryFrom<cst::NamedType> for crate::Type_ {
149 type Error = FromError;
150
151 fn try_from(node: cst::NamedType) -> Result<Self, Self::Error> {
158 Ok(Self::NamedType {
159 name: node
160 .name()
161 .ok_or(FromError::MissingNode)?
162 .text()
163 .to_string(),
164 })
165 }
166}
167
168impl TryFrom<cst::ListType> for crate::Type_ {
169 type Error = FromError;
170
171 fn try_from(node: cst::ListType) -> Result<Self, Self::Error> {
178 Ok(Self::List {
179 ty: Box::new(node.ty().ok_or(FromError::MissingNode)?.try_into()?),
180 })
181 }
182}
183
184impl TryFrom<cst::NonNullType> for crate::Type_ {
185 type Error = FromError;
186
187 fn try_from(node: cst::NonNullType) -> Result<Self, Self::Error> {
194 let named_type = node
195 .named_type()
196 .ok_or(FromError::MissingNode)
197 .and_then(|ty| ty.try_into());
198 let list_type = node
199 .list_type()
200 .ok_or(FromError::MissingNode)
201 .and_then(|ty| ty.try_into());
202
203 Ok(Self::NonNull {
204 ty: Box::new(named_type.or(list_type)?),
205 })
206 }
207}
208
209impl TryFrom<cst::Type> for crate::Type_ {
210 type Error = FromError;
211
212 fn try_from(node: cst::Type) -> Result<Self, Self::Error> {
219 match node {
220 cst::Type::NamedType(ty) => ty.try_into(),
221 cst::Type::ListType(ty) => ty.try_into(),
222 cst::Type::NonNullType(ty) => ty.try_into(),
223 }
224 }
225}
226
227impl TryFrom<cst::InputValueDefinition> for crate::InputValueDefinition {
228 type Error = FromError;
229
230 fn try_from(node: cst::InputValueDefinition) -> Result<Self, Self::Error> {
237 let name = node
238 .name()
239 .ok_or(FromError::MissingNode)?
240 .text()
241 .to_string();
242 let ty = node.ty().ok_or(FromError::MissingNode)?;
243 let mut encoder_node = Self::new(name, ty.try_into()?);
244
245 if let Some(description) = node.description() {
246 encoder_node.description(
247 description
248 .string_value()
249 .ok_or(FromError::MissingNode)?
250 .into(),
251 );
252 }
253
254 if let Some(default_value) = node.default_value() {
255 encoder_node.default_value(
257 default_value
258 .value()
259 .ok_or(FromError::MissingNode)?
260 .source_string(),
261 );
262 }
263
264 if let Some(directives) = node.directives() {
265 for directive in directives.directives() {
266 encoder_node.directive(directive.try_into()?);
267 }
268 }
269
270 Ok(encoder_node)
271 }
272}
273
274impl TryFrom<cst::ArgumentsDefinition> for crate::ArgumentsDefinition {
275 type Error = FromError;
276
277 fn try_from(node: cst::ArgumentsDefinition) -> Result<Self, Self::Error> {
284 let input_values = node
285 .input_value_definitions()
286 .map(|input_value| input_value.try_into())
287 .collect::<Result<Vec<_>, FromError>>()?;
288
289 Ok(Self::with_values(input_values))
290 }
291}
292
293impl TryFrom<cst::FieldDefinition> for crate::FieldDefinition {
294 type Error = FromError;
295
296 fn try_from(node: cst::FieldDefinition) -> Result<Self, Self::Error> {
303 let name = node
304 .name()
305 .ok_or(FromError::MissingNode)?
306 .text()
307 .to_string();
308 let ty = node.ty().ok_or(FromError::MissingNode)?.try_into()?;
309 let mut encoder_node = Self::new(name, ty);
310
311 if let Some(arguments_definition) = node.arguments_definition() {
312 for input_value in arguments_definition.input_value_definitions() {
313 encoder_node.arg(input_value.try_into()?);
314 }
315 }
316
317 if let Some(directives) = node.directives() {
318 for directive in directives.directives() {
319 encoder_node.directive(directive.try_into()?);
320 }
321 }
322
323 Ok(encoder_node)
324 }
325}
326
327impl TryFrom<cst::TypeCondition> for crate::TypeCondition {
328 type Error = FromError;
329
330 fn try_from(node: cst::TypeCondition) -> Result<Self, Self::Error> {
337 let named_type = node.named_type().ok_or(FromError::MissingNode)?;
338 let name = named_type
339 .name()
340 .ok_or(FromError::MissingNode)?
341 .text()
342 .to_string();
343 Ok(Self::new(name))
344 }
345}
346
347impl TryFrom<cst::Field> for crate::Field {
348 type Error = FromError;
349
350 fn try_from(node: cst::Field) -> Result<Self, Self::Error> {
357 let name = node
358 .name()
359 .ok_or(FromError::MissingNode)?
360 .text()
361 .to_string();
362
363 let mut encoder_node = Self::new(name);
364
365 if let Some(alias) = node.alias() {
366 let alias = alias
367 .name()
368 .ok_or(FromError::MissingNode)?
369 .text()
370 .to_string();
371 encoder_node.alias(Some(alias));
372 }
373
374 if let Some(arguments) = node.arguments() {
375 for argument in arguments.arguments() {
376 encoder_node.argument(argument.try_into()?);
377 }
378 }
379
380 if let Some(directives) = node.directives() {
381 for directive in directives.directives() {
382 encoder_node.directive(directive.try_into()?);
383 }
384 }
385
386 let selection_set = node
387 .selection_set()
388 .map(|selection_set| selection_set.try_into())
389 .transpose()?;
390 encoder_node.selection_set(selection_set);
391
392 Ok(encoder_node)
393 }
394}
395
396impl TryFrom<cst::FragmentSpread> for crate::FragmentSpread {
397 type Error = FromError;
398
399 fn try_from(node: cst::FragmentSpread) -> Result<Self, Self::Error> {
406 let name = node
407 .fragment_name()
408 .and_then(|fragment_name| fragment_name.name())
409 .ok_or(FromError::MissingNode)?
410 .text()
411 .to_string();
412 let mut encoder_node = Self::new(name);
413 if let Some(directives) = node.directives() {
414 for directive in directives.directives() {
415 encoder_node.directive(directive.try_into()?);
416 }
417 }
418 Ok(encoder_node)
419 }
420}
421
422impl TryFrom<cst::InlineFragment> for crate::InlineFragment {
423 type Error = FromError;
424
425 fn try_from(node: cst::InlineFragment) -> Result<Self, Self::Error> {
432 let selection_set = node
433 .selection_set()
434 .ok_or(FromError::MissingNode)?
435 .try_into()?;
436 let mut encoder_node = Self::new(selection_set);
437
438 let type_condition = node
439 .type_condition()
440 .map(|condition| condition.try_into())
441 .transpose()?;
442 encoder_node.type_condition(type_condition);
443
444 if let Some(directives) = node.directives() {
445 for directive in directives.directives() {
446 encoder_node.directive(directive.try_into()?);
447 }
448 }
449
450 Ok(encoder_node)
451 }
452}
453
454impl TryFrom<cst::Selection> for crate::Selection {
455 type Error = FromError;
456
457 fn try_from(node: cst::Selection) -> Result<Self, Self::Error> {
464 let encoder_node = match node {
465 cst::Selection::Field(field) => Self::Field(field.try_into()?),
466 cst::Selection::FragmentSpread(fragment) => Self::FragmentSpread(fragment.try_into()?),
467 cst::Selection::InlineFragment(fragment) => Self::InlineFragment(fragment.try_into()?),
468 };
469
470 Ok(encoder_node)
471 }
472}
473
474impl TryFrom<cst::SelectionSet> for crate::SelectionSet {
475 type Error = FromError;
476
477 fn try_from(node: cst::SelectionSet) -> Result<Self, Self::Error> {
484 let selections = node
485 .selections()
486 .map(|selection| selection.try_into())
487 .collect::<Result<Vec<_>, FromError>>()?;
488
489 Ok(Self::with_selections(selections))
490 }
491}
492
493impl TryFrom<cst::OperationType> for crate::OperationType {
494 type Error = FromError;
495
496 fn try_from(node: cst::OperationType) -> Result<Self, Self::Error> {
503 if node.query_token().is_some() {
504 Ok(Self::Query)
505 } else if node.mutation_token().is_some() {
506 Ok(Self::Mutation)
507 } else if node.subscription_token().is_some() {
508 Ok(Self::Subscription)
509 } else {
510 Err(FromError::MissingNode)
511 }
512 }
513}
514
515impl TryFrom<cst::VariableDefinition> for crate::VariableDefinition {
516 type Error = FromError;
517
518 fn try_from(node: cst::VariableDefinition) -> Result<Self, Self::Error> {
525 let name = node
526 .variable()
527 .ok_or(FromError::MissingNode)?
528 .name()
529 .ok_or(FromError::MissingNode)?
530 .text()
531 .to_string();
532 let ty = node.ty().ok_or(FromError::MissingNode)?.try_into()?;
533
534 let mut encoder_node = Self::new(name, ty);
535
536 if let Some(default_value) = node.default_value() {
537 encoder_node.default_value(default_value.try_into()?);
538 }
539
540 if let Some(directives) = node.directives() {
541 for directive in directives.directives() {
542 encoder_node.directive(directive.try_into()?);
543 }
544 }
545
546 Ok(encoder_node)
547 }
548}
549
550impl TryFrom<cst::OperationDefinition> for crate::OperationDefinition {
551 type Error = FromError;
552
553 fn try_from(node: cst::OperationDefinition) -> Result<Self, Self::Error> {
560 let operation_type = node
561 .operation_type()
562 .ok_or(FromError::MissingNode)?
563 .try_into()?;
564 let selection_set = node
565 .selection_set()
566 .ok_or(FromError::MissingNode)?
567 .try_into()?;
568
569 let mut encoder_node = Self::new(operation_type, selection_set);
570
571 if let Some(name) = node.name() {
572 encoder_node.name(Some(name.text().to_string()));
573 }
574
575 if let Some(variable_definitions) = node.variable_definitions() {
576 for variable_definition in variable_definitions.variable_definitions() {
577 encoder_node.variable_definition(variable_definition.try_into()?);
578 }
579 }
580
581 if let Some(directives) = node.directives() {
582 for directive in directives.directives() {
583 encoder_node.directive(directive.try_into()?);
584 }
585 }
586
587 Ok(encoder_node)
588 }
589}
590
591impl TryFrom<cst::FragmentDefinition> for crate::FragmentDefinition {
592 type Error = FromError;
593
594 fn try_from(node: cst::FragmentDefinition) -> Result<Self, Self::Error> {
601 let name = node
602 .fragment_name()
603 .ok_or(FromError::MissingNode)?
604 .name()
605 .ok_or(FromError::MissingNode)?
606 .text()
607 .to_string();
608 let type_condition = node
609 .type_condition()
610 .ok_or(FromError::MissingNode)?
611 .try_into()?;
612 let selection_set = node
613 .selection_set()
614 .ok_or(FromError::MissingNode)?
615 .try_into()?;
616
617 let mut encoder_node = Self::new(name, type_condition, selection_set);
618 if let Some(directives) = node.directives() {
619 for directive in directives.directives() {
620 encoder_node.directive(directive.try_into()?);
621 }
622 }
623
624 Ok(encoder_node)
625 }
626}
627
628impl TryFrom<cst::DirectiveDefinition> for crate::DirectiveDefinition {
629 type Error = FromError;
630
631 fn try_from(node: cst::DirectiveDefinition) -> Result<Self, Self::Error> {
638 let name = node
639 .name()
640 .ok_or(FromError::MissingNode)?
641 .text()
642 .to_string();
643
644 let mut encoder_node = Self::new(name);
645
646 let description = node
647 .description()
648 .and_then(|description| description.string_value())
649 .map(|string| string.into());
650 if let Some(description) = description {
651 encoder_node.description(description);
652 }
653
654 if let Some(arguments_definition) = node.arguments_definition() {
655 for input_value in arguments_definition.input_value_definitions() {
656 encoder_node.arg(input_value.try_into()?);
657 }
658 }
659
660 if let Some(directive_locations) = node.directive_locations() {
661 let locations = directive_locations
662 .directive_locations()
663 .map(|location| location.text().map(|token| token.to_string()));
664 for location in locations {
665 let location = location.ok_or(FromError::MissingNode)?;
668 encoder_node.location(location);
669 }
670 }
671
672 if node.repeatable_token().is_some() {
673 encoder_node.repeatable();
674 }
675
676 Ok(encoder_node)
677 }
678}
679
680fn apply_root_operation_type_definitions(
681 encoder_node: &mut crate::SchemaDefinition,
682 type_definitions: impl Iterator<Item = cst::RootOperationTypeDefinition>,
683) -> Result<(), FromError> {
684 for root in type_definitions {
685 let operation_type = root.operation_type().ok_or(FromError::MissingNode)?;
686 let name = root
687 .named_type()
688 .ok_or(FromError::MissingNode)?
689 .name()
690 .ok_or(FromError::MissingNode)?
691 .text()
692 .to_string();
693 if operation_type.query_token().is_some() {
694 encoder_node.query(name);
695 } else if operation_type.mutation_token().is_some() {
696 encoder_node.mutation(name);
697 } else if operation_type.subscription_token().is_some() {
698 encoder_node.subscription(name);
699 } else {
700 return Err(FromError::MissingNode);
701 }
702 }
703
704 Ok(())
705}
706
707impl TryFrom<cst::SchemaDefinition> for crate::SchemaDefinition {
708 type Error = FromError;
709
710 fn try_from(node: cst::SchemaDefinition) -> Result<Self, Self::Error> {
717 let mut encoder_node = Self::new();
718
719 let description = node
720 .description()
721 .and_then(|description| description.string_value())
722 .map(|string| string.into());
723 if let Some(description) = description {
724 encoder_node.description(description);
725 }
726
727 if let Some(directives) = node.directives() {
728 for directive in directives.directives() {
729 encoder_node.directive(directive.try_into()?);
730 }
731 }
732
733 apply_root_operation_type_definitions(
734 &mut encoder_node,
735 node.root_operation_type_definitions(),
736 )?;
737
738 Ok(encoder_node)
739 }
740}
741
742impl TryFrom<cst::ScalarTypeDefinition> for crate::ScalarDefinition {
743 type Error = FromError;
744
745 fn try_from(node: cst::ScalarTypeDefinition) -> Result<Self, Self::Error> {
752 let name = node
753 .name()
754 .ok_or(FromError::MissingNode)?
755 .text()
756 .to_string();
757 let mut encoder_node = Self::new(name);
758
759 let description = node
760 .description()
761 .and_then(|description| description.string_value())
762 .map(|string| string.into());
763 if let Some(description) = description {
764 encoder_node.description(description);
765 }
766
767 if let Some(directives) = node.directives() {
768 for directive in directives.directives() {
769 encoder_node.directive(directive.try_into()?);
770 }
771 }
772
773 Ok(encoder_node)
774 }
775}
776
777impl TryFrom<cst::ObjectTypeDefinition> for crate::ObjectDefinition {
778 type Error = FromError;
779
780 fn try_from(node: cst::ObjectTypeDefinition) -> Result<Self, Self::Error> {
787 let name = node
788 .name()
789 .ok_or(FromError::MissingNode)?
790 .text()
791 .to_string();
792 let mut encoder_node = Self::new(name);
793
794 let description = node
795 .description()
796 .and_then(|description| description.string_value())
797 .map(|string| string.into());
798 if let Some(description) = description {
799 encoder_node.description(description);
800 }
801
802 if let Some(directives) = node.directives() {
803 for directive in directives.directives() {
804 encoder_node.directive(directive.try_into()?);
805 }
806 }
807
808 if let Some(implements_interfaces) = node.implements_interfaces() {
809 for implements in implements_interfaces.named_types() {
810 let name = implements
811 .name()
812 .ok_or(FromError::MissingNode)?
813 .text()
814 .to_string();
815 encoder_node.interface(name);
816 }
817 }
818
819 if let Some(field_definitions) = node.fields_definition() {
820 for field_definition in field_definitions.field_definitions() {
821 encoder_node.field(field_definition.try_into()?);
822 }
823 }
824
825 Ok(encoder_node)
826 }
827}
828
829impl TryFrom<cst::InterfaceTypeDefinition> for crate::InterfaceDefinition {
830 type Error = FromError;
831
832 fn try_from(node: cst::InterfaceTypeDefinition) -> Result<Self, Self::Error> {
839 let name = node
840 .name()
841 .ok_or(FromError::MissingNode)?
842 .text()
843 .to_string();
844 let mut encoder_node = Self::new(name);
845
846 let description = node
847 .description()
848 .and_then(|description| description.string_value())
849 .map(|string| string.into());
850 if let Some(description) = description {
851 encoder_node.description(description);
852 }
853
854 if let Some(directives) = node.directives() {
855 for directive in directives.directives() {
856 encoder_node.directive(directive.try_into()?);
857 }
858 }
859
860 if let Some(implements_interfaces) = node.implements_interfaces() {
861 for implements in implements_interfaces.named_types() {
862 let name = implements
863 .name()
864 .ok_or(FromError::MissingNode)?
865 .text()
866 .to_string();
867 encoder_node.interface(name);
868 }
869 }
870
871 if let Some(field_definitions) = node.fields_definition() {
872 for field_definition in field_definitions.field_definitions() {
873 encoder_node.field(field_definition.try_into()?);
874 }
875 }
876
877 Ok(encoder_node)
878 }
879}
880
881impl TryFrom<cst::UnionTypeDefinition> for crate::UnionDefinition {
882 type Error = FromError;
883
884 fn try_from(node: cst::UnionTypeDefinition) -> Result<Self, Self::Error> {
891 let name = node
892 .name()
893 .ok_or(FromError::MissingNode)?
894 .text()
895 .to_string();
896 let mut encoder_node = Self::new(name);
897
898 let description = node
899 .description()
900 .and_then(|description| description.string_value())
901 .map(|string| string.into());
902 if let Some(description) = description {
903 encoder_node.description(description);
904 }
905
906 if let Some(directives) = node.directives() {
907 for directive in directives.directives() {
908 encoder_node.directive(directive.try_into()?);
909 }
910 }
911
912 if let Some(members) = node.union_member_types() {
913 for member in members.named_types() {
914 encoder_node.member(
915 member
916 .name()
917 .ok_or(FromError::MissingNode)?
918 .text()
919 .to_string(),
920 );
921 }
922 }
923
924 Ok(encoder_node)
925 }
926}
927
928impl TryFrom<cst::EnumValueDefinition> for crate::EnumValue {
929 type Error = FromError;
930
931 fn try_from(node: cst::EnumValueDefinition) -> Result<Self, Self::Error> {
938 let name = node
939 .enum_value()
940 .ok_or(FromError::MissingNode)?
941 .name()
942 .ok_or(FromError::MissingNode)?
943 .text()
944 .to_string();
945 let mut encoder_node = Self::new(name);
946
947 let description = node
948 .description()
949 .and_then(|description| description.string_value())
950 .map(|string| string.into());
951 if let Some(description) = description {
952 encoder_node.description(description);
953 }
954
955 if let Some(directives) = node.directives() {
956 for directive in directives.directives() {
957 encoder_node.directive(directive.try_into()?);
958 }
959 }
960
961 Ok(encoder_node)
962 }
963}
964
965impl TryFrom<cst::EnumTypeDefinition> for crate::EnumDefinition {
966 type Error = FromError;
967
968 fn try_from(node: cst::EnumTypeDefinition) -> Result<Self, Self::Error> {
975 let name = node
976 .name()
977 .ok_or(FromError::MissingNode)?
978 .text()
979 .to_string();
980 let mut encoder_node = Self::new(name);
981
982 let description = node
983 .description()
984 .and_then(|description| description.string_value())
985 .map(|string| string.into());
986 if let Some(description) = description {
987 encoder_node.description(description);
988 }
989
990 if let Some(directives) = node.directives() {
991 for directive in directives.directives() {
992 encoder_node.directive(directive.try_into()?);
993 }
994 }
995
996 if let Some(values) = node.enum_values_definition() {
997 for value in values.enum_value_definitions() {
998 encoder_node.value(value.try_into()?);
999 }
1000 }
1001
1002 Ok(encoder_node)
1003 }
1004}
1005
1006impl TryFrom<cst::InputValueDefinition> for crate::InputField {
1007 type Error = FromError;
1008
1009 fn try_from(node: cst::InputValueDefinition) -> Result<Self, Self::Error> {
1016 let name = node
1017 .name()
1018 .ok_or(FromError::MissingNode)?
1019 .text()
1020 .to_string();
1021 let ty = node.ty().ok_or(FromError::MissingNode)?;
1022 let mut encoder_node = Self::new(name, ty.try_into()?);
1023
1024 if let Some(description) = node.description() {
1025 encoder_node.description(
1026 description
1027 .string_value()
1028 .ok_or(FromError::MissingNode)?
1029 .into(),
1030 );
1031 }
1032
1033 if let Some(default_value) = node.default_value() {
1034 encoder_node.default_value(
1036 default_value
1037 .value()
1038 .ok_or(FromError::MissingNode)?
1039 .source_string(),
1040 );
1041 }
1042
1043 if let Some(directives) = node.directives() {
1044 for directive in directives.directives() {
1045 encoder_node.directive(directive.try_into()?);
1046 }
1047 }
1048
1049 Ok(encoder_node)
1050 }
1051}
1052
1053impl TryFrom<cst::InputObjectTypeDefinition> for crate::InputObjectDefinition {
1054 type Error = FromError;
1055
1056 fn try_from(node: cst::InputObjectTypeDefinition) -> Result<Self, Self::Error> {
1063 let name = node
1064 .name()
1065 .ok_or(FromError::MissingNode)?
1066 .text()
1067 .to_string();
1068 let mut encoder_node = Self::new(name);
1069
1070 let description = node
1071 .description()
1072 .and_then(|description| description.string_value())
1073 .and_then(|string| string.try_into().ok());
1074 if let Some(description) = description {
1075 encoder_node.description(description);
1076 }
1077
1078 if let Some(directives) = node.directives() {
1079 for directive in directives.directives() {
1080 encoder_node.directive(directive.try_into()?);
1081 }
1082 }
1083
1084 if let Some(field_definitions) = node.input_fields_definition() {
1085 for field_definition in field_definitions.input_value_definitions() {
1086 encoder_node.field(field_definition.try_into()?);
1087 }
1088 }
1089
1090 Ok(encoder_node)
1091 }
1092}
1093
1094impl TryFrom<cst::SchemaExtension> for crate::SchemaDefinition {
1095 type Error = FromError;
1096
1097 fn try_from(node: cst::SchemaExtension) -> Result<Self, Self::Error> {
1104 let mut encoder_node = Self::new();
1105
1106 if let Some(directives) = node.directives() {
1107 for directive in directives.directives() {
1108 encoder_node.directive(directive.try_into()?);
1109 }
1110 }
1111
1112 apply_root_operation_type_definitions(
1113 &mut encoder_node,
1114 node.root_operation_type_definitions(),
1115 )?;
1116
1117 encoder_node.extend();
1118
1119 Ok(encoder_node)
1120 }
1121}
1122
1123impl TryFrom<cst::ScalarTypeExtension> for crate::ScalarDefinition {
1124 type Error = FromError;
1125
1126 fn try_from(node: cst::ScalarTypeExtension) -> Result<Self, Self::Error> {
1133 let name = node
1134 .name()
1135 .ok_or(FromError::MissingNode)?
1136 .text()
1137 .to_string();
1138 let mut encoder_node = Self::new(name);
1139
1140 if let Some(directives) = node.directives() {
1141 for directive in directives.directives() {
1142 encoder_node.directive(directive.try_into()?);
1143 }
1144 }
1145
1146 encoder_node.extend();
1147
1148 Ok(encoder_node)
1149 }
1150}
1151
1152impl TryFrom<cst::ObjectTypeExtension> for crate::ObjectDefinition {
1153 type Error = FromError;
1154
1155 fn try_from(node: cst::ObjectTypeExtension) -> Result<Self, Self::Error> {
1162 let name = node
1163 .name()
1164 .ok_or(FromError::MissingNode)?
1165 .text()
1166 .to_string();
1167 let mut encoder_node = Self::new(name);
1168
1169 if let Some(directives) = node.directives() {
1170 for directive in directives.directives() {
1171 encoder_node.directive(directive.try_into()?);
1172 }
1173 }
1174
1175 if let Some(implements_interfaces) = node.implements_interfaces() {
1176 for implements in implements_interfaces.named_types() {
1177 let name = implements
1178 .name()
1179 .ok_or(FromError::MissingNode)?
1180 .text()
1181 .to_string();
1182 encoder_node.interface(name);
1183 }
1184 }
1185
1186 if let Some(field_definitions) = node.fields_definition() {
1187 for field_definition in field_definitions.field_definitions() {
1188 encoder_node.field(field_definition.try_into()?);
1189 }
1190 }
1191
1192 encoder_node.extend();
1193
1194 Ok(encoder_node)
1195 }
1196}
1197
1198impl TryFrom<cst::InterfaceTypeExtension> for crate::InterfaceDefinition {
1199 type Error = FromError;
1200
1201 fn try_from(node: cst::InterfaceTypeExtension) -> Result<Self, Self::Error> {
1208 let name = node
1209 .name()
1210 .ok_or(FromError::MissingNode)?
1211 .text()
1212 .to_string();
1213 let mut encoder_node = Self::new(name);
1214
1215 if let Some(directives) = node.directives() {
1216 for directive in directives.directives() {
1217 encoder_node.directive(directive.try_into()?);
1218 }
1219 }
1220
1221 if let Some(implements_interfaces) = node.implements_interfaces() {
1222 for implements in implements_interfaces.named_types() {
1223 let name = implements
1224 .name()
1225 .ok_or(FromError::MissingNode)?
1226 .text()
1227 .to_string();
1228 encoder_node.interface(name);
1229 }
1230 }
1231
1232 if let Some(field_definitions) = node.fields_definition() {
1233 for field_definition in field_definitions.field_definitions() {
1234 encoder_node.field(field_definition.try_into()?);
1235 }
1236 }
1237
1238 encoder_node.extend();
1239
1240 Ok(encoder_node)
1241 }
1242}
1243
1244impl TryFrom<cst::UnionTypeExtension> for crate::UnionDefinition {
1245 type Error = FromError;
1246
1247 fn try_from(node: cst::UnionTypeExtension) -> Result<Self, Self::Error> {
1254 let name = node
1255 .name()
1256 .ok_or(FromError::MissingNode)?
1257 .text()
1258 .to_string();
1259 let mut encoder_node = Self::new(name);
1260
1261 if let Some(directives) = node.directives() {
1262 for directive in directives.directives() {
1263 encoder_node.directive(directive.try_into()?);
1264 }
1265 }
1266
1267 if let Some(members) = node.union_member_types() {
1268 for member in members.named_types() {
1269 encoder_node.member(
1270 member
1271 .name()
1272 .ok_or(FromError::MissingNode)?
1273 .text()
1274 .to_string(),
1275 );
1276 }
1277 }
1278
1279 encoder_node.extend();
1280
1281 Ok(encoder_node)
1282 }
1283}
1284
1285impl TryFrom<cst::EnumTypeExtension> for crate::EnumDefinition {
1286 type Error = FromError;
1287
1288 fn try_from(node: cst::EnumTypeExtension) -> Result<Self, Self::Error> {
1295 let name = node
1296 .name()
1297 .ok_or(FromError::MissingNode)?
1298 .text()
1299 .to_string();
1300 let mut encoder_node = Self::new(name);
1301
1302 if let Some(directives) = node.directives() {
1303 for directive in directives.directives() {
1304 encoder_node.directive(directive.try_into()?);
1305 }
1306 }
1307
1308 if let Some(values) = node.enum_values_definition() {
1309 for value in values.enum_value_definitions() {
1310 encoder_node.value(value.try_into()?);
1311 }
1312 }
1313
1314 encoder_node.extend();
1315
1316 Ok(encoder_node)
1317 }
1318}
1319
1320impl TryFrom<cst::InputObjectTypeExtension> for crate::InputObjectDefinition {
1321 type Error = FromError;
1322
1323 fn try_from(node: cst::InputObjectTypeExtension) -> Result<Self, Self::Error> {
1330 let name = node
1331 .name()
1332 .ok_or(FromError::MissingNode)?
1333 .text()
1334 .to_string();
1335 let mut encoder_node = Self::new(name);
1336
1337 if let Some(directives) = node.directives() {
1338 for directive in directives.directives() {
1339 encoder_node.directive(directive.try_into()?);
1340 }
1341 }
1342
1343 if let Some(field_definitions) = node.input_fields_definition() {
1344 for field_definition in field_definitions.input_value_definitions() {
1345 encoder_node.field(field_definition.try_into()?);
1346 }
1347 }
1348
1349 encoder_node.extend();
1350
1351 Ok(encoder_node)
1352 }
1353}
1354
1355impl TryFrom<cst::Document> for crate::Document {
1356 type Error = FromError;
1357
1358 fn try_from(node: cst::Document) -> Result<Self, Self::Error> {
1365 let mut encoder_node = Self::new();
1366
1367 for definition in node.definitions() {
1368 match definition {
1369 cst::Definition::OperationDefinition(def) => {
1370 encoder_node.operation(def.try_into()?)
1371 }
1372 cst::Definition::FragmentDefinition(def) => encoder_node.fragment(def.try_into()?),
1373 cst::Definition::DirectiveDefinition(def) => {
1374 encoder_node.directive(def.try_into()?)
1375 }
1376 cst::Definition::SchemaDefinition(def) => encoder_node.schema(def.try_into()?),
1377 cst::Definition::ScalarTypeDefinition(def) => encoder_node.scalar(def.try_into()?),
1378 cst::Definition::ObjectTypeDefinition(def) => encoder_node.object(def.try_into()?),
1379 cst::Definition::InterfaceTypeDefinition(def) => {
1380 encoder_node.interface(def.try_into()?)
1381 }
1382 cst::Definition::UnionTypeDefinition(def) => encoder_node.union(def.try_into()?),
1383 cst::Definition::EnumTypeDefinition(def) => encoder_node.enum_(def.try_into()?),
1384 cst::Definition::InputObjectTypeDefinition(def) => {
1385 encoder_node.input_object(def.try_into()?)
1386 }
1387 cst::Definition::SchemaExtension(ext) => encoder_node.schema(ext.try_into()?),
1388 cst::Definition::ScalarTypeExtension(ext) => encoder_node.scalar(ext.try_into()?),
1389 cst::Definition::ObjectTypeExtension(ext) => encoder_node.object(ext.try_into()?),
1390 cst::Definition::InterfaceTypeExtension(ext) => {
1391 encoder_node.interface(ext.try_into()?)
1392 }
1393 cst::Definition::UnionTypeExtension(ext) => encoder_node.union(ext.try_into()?),
1394 cst::Definition::EnumTypeExtension(ext) => encoder_node.enum_(ext.try_into()?),
1395 cst::Definition::InputObjectTypeExtension(ext) => {
1396 encoder_node.input_object(ext.try_into()?)
1397 }
1398 }
1399 }
1400
1401 Ok(encoder_node)
1402 }
1403}
1404
1405#[cfg(test)]
1406mod tests {
1407 use crate::Document;
1408 use apollo_parser::Parser;
1409
1410 #[test]
1411 fn operation_definition() {
1412 let parser = Parser::new(
1413 r#"
1414query HeroForEpisode($ep: Episode!) {
1415 hero(episode: $ep) {
1416 name
1417 ... on Droid {
1418 primaryFunction
1419 }
1420 ... on Human {
1421 height
1422 }
1423 }
1424}
1425"#,
1426 );
1427 let cst = parser.parse();
1428 let doc = cst.document();
1429
1430 let encoder = Document::try_from(doc).unwrap();
1431 assert_eq!(
1432 encoder.to_string(),
1433 r#"
1434query HeroForEpisode($ep: Episode!) {
1435 hero(episode: $ep) {
1436 name
1437 ... on Droid {
1438 primaryFunction
1439 }
1440 ... on Human {
1441 height
1442 }
1443 }
1444}
1445"#
1446 .trim_start()
1447 );
1448 }
1449
1450 #[test]
1451 fn fragment_definition() {
1452 let parser = Parser::new(
1453 r#"
1454fragment FragmentDefinition on VeryRealType {
1455 id
1456 title
1457 text
1458}
1459"#,
1460 );
1461 let cst = parser.parse();
1462 let doc = cst.document();
1463
1464 let encoder = Document::try_from(doc).unwrap();
1465 assert_eq!(
1466 encoder.to_string(),
1467 r#"
1468fragment FragmentDefinition on VeryRealType {
1469 id
1470 title
1471 text
1472}
1473"#
1474 .trim_start()
1475 );
1476 }
1477
1478 #[test]
1479 fn directive_definition() {
1480 let parser = Parser::new(
1481 r#"
1482directive @withDeprecatedArgs(
1483 deprecatedArg: String @deprecated(reason: "Use `newArg`")
1484 newArg: String
1485) on FIELD
1486"#,
1487 );
1488 let cst = parser.parse();
1489 let doc = cst.document();
1490
1491 let encoder = Document::try_from(doc).unwrap();
1492 assert_eq!(encoder.to_string(), r#"
1493directive @withDeprecatedArgs(deprecatedArg: String @deprecated(reason: "Use `newArg`"), newArg: String) on FIELD
1494"#.trim_start());
1495 }
1496
1497 #[test]
1498 fn schema_definition() {
1499 let parser = Parser::new(
1500 r#"
1501schema {
1502 query: Query
1503 subscription: Subscription
1504}
1505extend schema {
1506 mutation: Mutation
1507}
1508"#,
1509 );
1510 let cst = parser.parse();
1511 let doc = cst.document();
1512
1513 let encoder = Document::try_from(doc).unwrap();
1514 assert_eq!(
1515 encoder.to_string(),
1516 r#"
1517schema {
1518 query: Query
1519 subscription: Subscription
1520}
1521extend schema {
1522 mutation: Mutation
1523}
1524"#
1525 .trim_start()
1526 );
1527 }
1528
1529 #[test]
1530 fn scalar_definition() {
1531 let parser = Parser::new(
1532 r#"
1533scalar Date
1534extend scalar Date @directive
1535"#,
1536 );
1537 let cst = parser.parse();
1538 let doc = cst.document();
1539
1540 let encoder = Document::try_from(doc).unwrap();
1541 assert_eq!(
1542 encoder.to_string(),
1543 r#"
1544scalar Date
1545extend scalar Date @directive
1546"#
1547 .trim_start()
1548 );
1549 }
1550
1551 #[test]
1552 fn object_type_definition() {
1553 let parser = Parser::new(
1554 r#"
1555type User implements X & Y
1556 @join__owner(graph: USERS)
1557 @join__type(graph: USERS, key: "email")
1558{
1559 email: String! @join__field(graph: USERS)
1560 id: String! @join__field(graph: USERS)
1561 name: String @join__field(graph: USERS)
1562 userProduct: UserProduct @join__field(graph: USERS)
1563}
1564"#,
1565 );
1566 let cst = parser.parse();
1567 let doc = cst.document();
1568
1569 let encoder = Document::try_from(doc).unwrap();
1570 assert_eq!(
1571 encoder.to_string(),
1572 r#"
1573type User implements X & Y @join__owner(graph: USERS) @join__type(graph: USERS, key: "email") {
1574 email: String! @join__field(graph: USERS)
1575 id: String! @join__field(graph: USERS)
1576 name: String @join__field(graph: USERS)
1577 userProduct: UserProduct @join__field(graph: USERS)
1578}
1579"#
1580 .trim_start()
1581 );
1582 }
1583
1584 #[test]
1585 fn interface_definition() {
1586 let parser = Parser::new(
1587 r#"
1588interface X {
1589 email: String!
1590}
1591interface Y {
1592 id: ID!
1593}
1594interface Z implements X & Y @inaccessible {}
1595"#,
1596 );
1597 let cst = parser.parse();
1598 let doc = cst.document();
1599
1600 let encoder = Document::try_from(doc).unwrap();
1601 assert_eq!(
1602 encoder.to_string(),
1603 r#"
1604interface X {
1605 email: String!
1606}
1607interface Y {
1608 id: ID!
1609}
1610interface Z implements X& Y @inaccessible {
1611}
1612"#
1613 .trim_start()
1614 );
1615 }
1616
1617 #[test]
1618 fn union_definition() {
1619 let parser = Parser::new(
1620 r#"
1621union UnionType = X | Y | Z
1622"#,
1623 );
1624 let cst = parser.parse();
1625 let doc = cst.document();
1626
1627 let encoder = Document::try_from(doc).unwrap();
1628 assert_eq!(
1629 encoder.to_string(),
1630 r#"
1631union UnionType = X | Y | Z
1632"#
1633 .trim_start()
1634 );
1635 }
1636
1637 #[test]
1638 fn enum_definition() {
1639 let parser = Parser::new(
1640 r#"
1641"Documentation for an enum"
1642enum EnumType {
1643 X
1644 "This is Y"
1645 Y
1646 Z @test()
1647}
1648"#,
1649 );
1650 let cst = parser.parse();
1651 let doc = cst.document();
1652
1653 let encoder = Document::try_from(doc).unwrap();
1654 assert_eq!(
1655 encoder.to_string(),
1656 r#"
1657"Documentation for an enum"
1658enum EnumType {
1659 X
1660 "This is Y"
1661 Y
1662 Z @test
1663}
1664"#
1665 .trim_start()
1666 );
1667 }
1668}