1use crate::ast;
65use crate::collections::HashMap;
66use crate::collections::IndexMap;
67use crate::collections::IndexSet;
68use crate::name;
69use crate::parser::FileId;
70use crate::parser::Parser;
71use crate::parser::SourceSpan;
72use crate::ty;
73use crate::validation::DiagnosticList;
74use crate::validation::Valid;
75use crate::validation::WithErrors;
76pub use crate::Name;
77use crate::Node;
78use std::path::Path;
79use std::sync::OnceLock;
80
81mod component;
82mod from_ast;
83mod serialize;
84pub(crate) mod validation;
85
86pub use self::component::Component;
87pub use self::component::ComponentName;
88pub use self::component::ComponentOrigin;
89pub use self::component::ExtensionId;
90pub use self::from_ast::SchemaBuilder;
91pub use crate::ast::Directive;
92pub use crate::ast::DirectiveDefinition;
93pub use crate::ast::DirectiveLocation;
94pub use crate::ast::EnumValueDefinition;
95pub use crate::ast::FieldDefinition;
96pub use crate::ast::InputValueDefinition;
97pub use crate::ast::NamedType;
98pub use crate::ast::Type;
99pub use crate::ast::Value;
100
101#[derive(Clone)]
103pub struct Schema {
104 pub sources: crate::parser::SourceMap,
108
109 pub schema_definition: Node<SchemaDefinition>,
111
112 pub directive_definitions: IndexMap<Name, Node<DirectiveDefinition>>,
114
115 pub types: IndexMap<NamedType, ExtendedType>,
128
129 pub validate_default_values: bool,
135}
136
137#[derive(Debug, Clone, PartialEq, Eq, Default)]
140pub struct SchemaDefinition {
141 pub description: Option<Node<str>>,
142 pub directives: DirectiveList,
143
144 pub query: Option<ComponentName>,
146
147 pub mutation: Option<ComponentName>,
149
150 pub subscription: Option<ComponentName>,
152}
153
154#[derive(Clone, Eq, PartialEq, Hash, Default)]
164pub struct DirectiveList(pub Vec<Component<Directive>>);
165
166#[derive(Debug, Clone, PartialEq, Eq)]
170pub enum ExtendedType {
171 Scalar(Node<ScalarType>),
172 Object(Node<ObjectType>),
173 Interface(Node<InterfaceType>),
174 Union(Node<UnionType>),
175 Enum(Node<EnumType>),
176 InputObject(Node<InputObjectType>),
177}
178
179#[derive(Debug, Clone, PartialEq, Eq, Hash)]
182pub struct ScalarType {
183 pub description: Option<Node<str>>,
184 pub name: Name,
185 pub directives: DirectiveList,
186}
187
188#[derive(Debug, Clone, PartialEq, Eq)]
191pub struct ObjectType {
192 pub description: Option<Node<str>>,
193 pub name: Name,
194 pub implements_interfaces: IndexSet<ComponentName>,
195 pub directives: DirectiveList,
196
197 pub fields: IndexMap<Name, Component<FieldDefinition>>,
202}
203
204#[derive(Debug, Clone, PartialEq, Eq)]
205pub struct InterfaceType {
206 pub description: Option<Node<str>>,
207 pub name: Name,
208 pub implements_interfaces: IndexSet<ComponentName>,
209
210 pub directives: DirectiveList,
211
212 pub fields: IndexMap<Name, Component<FieldDefinition>>,
217}
218
219#[derive(Debug, Clone, PartialEq, Eq)]
222pub struct UnionType {
223 pub description: Option<Node<str>>,
224 pub name: Name,
225 pub directives: DirectiveList,
226
227 pub members: IndexSet<ComponentName>,
231}
232
233#[derive(Debug, Clone, PartialEq, Eq)]
236pub struct EnumType {
237 pub description: Option<Node<str>>,
238 pub name: Name,
239 pub directives: DirectiveList,
240 pub values: IndexMap<Name, Component<EnumValueDefinition>>,
241}
242
243#[derive(Debug, Clone, PartialEq, Eq)]
246pub struct InputObjectType {
247 pub description: Option<Node<str>>,
248 pub name: Name,
249 pub directives: DirectiveList,
250 pub fields: IndexMap<Name, Component<InputValueDefinition>>,
251}
252
253#[derive(Debug, Default, Clone, PartialEq, Eq)]
278pub struct Implementers {
279 pub objects: IndexSet<Name>,
281 pub interfaces: IndexSet<Name>,
283}
284
285#[derive(thiserror::Error, Debug, Clone)]
287pub(crate) enum BuildError {
288 #[error("a schema document must not contain {describe}")]
289 ExecutableDefinition { describe: &'static str },
290
291 #[error("must not have multiple `schema` definitions")]
292 SchemaDefinitionCollision {
293 previous_location: Option<SourceSpan>,
294 },
295
296 #[error("the directive `@{name}` is defined multiple times in the schema")]
297 DirectiveDefinitionCollision {
298 previous_location: Option<SourceSpan>,
299 name: Name,
300 },
301
302 #[error("the type `{name}` is defined multiple times in the schema")]
303 TypeDefinitionCollision {
304 previous_location: Option<SourceSpan>,
305 name: Name,
306 },
307
308 #[error("built-in scalar definitions must be omitted")]
309 BuiltInScalarTypeRedefinition,
310
311 #[error("schema extension without a schema definition")]
312 OrphanSchemaExtension,
313
314 #[error("type extension for undefined type `{name}`")]
315 OrphanTypeExtension { name: Name },
316
317 #[error("adding {describe_ext}, but `{name}` is {describe_def}")]
318 TypeExtensionKindMismatch {
319 name: Name,
320 describe_ext: &'static str,
321 def_location: Option<SourceSpan>,
322 describe_def: &'static str,
323 },
324
325 #[error("duplicate definitions for the `{operation_type}` root operation type")]
326 DuplicateRootOperation {
327 previous_location: Option<SourceSpan>,
328 operation_type: &'static str,
329 },
330
331 #[error(
332 "object type `{type_name}` implements interface `{name_at_previous_location}` \
333 more than once"
334 )]
335 DuplicateImplementsInterfaceInObject {
336 name_at_previous_location: Name,
337 type_name: Name,
338 },
339
340 #[error(
341 "interface type `{type_name}` implements interface `{name_at_previous_location}` \
342 more than once"
343 )]
344 DuplicateImplementsInterfaceInInterface {
345 name_at_previous_location: Name,
346 type_name: Name,
347 },
348
349 #[error(
350 "duplicate definitions for the `{name_at_previous_location}` \
351 field of object type `{type_name}`"
352 )]
353 ObjectFieldNameCollision {
354 name_at_previous_location: Name,
355 type_name: Name,
356 },
357
358 #[error(
359 "duplicate definitions for the `{name_at_previous_location}` \
360 field of interface type `{type_name}`"
361 )]
362 InterfaceFieldNameCollision {
363 name_at_previous_location: Name,
364 type_name: Name,
365 },
366
367 #[error(
368 "duplicate definitions for the `{name_at_previous_location}` \
369 value of enum type `{type_name}`"
370 )]
371 EnumValueNameCollision {
372 name_at_previous_location: Name,
373 type_name: Name,
374 },
375
376 #[error(
377 "duplicate definitions for the `{name_at_previous_location}` \
378 member of union type `{type_name}`"
379 )]
380 UnionMemberNameCollision {
381 name_at_previous_location: Name,
382 type_name: Name,
383 },
384
385 #[error(
386 "duplicate definitions for the `{name_at_previous_location}` \
387 field of input object type `{type_name}`"
388 )]
389 InputFieldNameCollision {
390 name_at_previous_location: Name,
391 type_name: Name,
392 },
393}
394
395#[derive(Debug, Clone, PartialEq, Eq)]
397pub enum FieldLookupError<'schema> {
398 NoSuchType,
399 NoSuchField(&'schema NamedType, &'schema ExtendedType),
400}
401
402impl Schema {
403 #[allow(clippy::new_without_default)] pub fn new() -> Self {
409 SchemaBuilder::new().build().unwrap()
410 }
411
412 #[allow(clippy::result_large_err)] pub fn parse(
418 source_text: impl Into<String>,
419 path: impl AsRef<Path>,
420 ) -> Result<Self, WithErrors<Self>> {
421 Parser::default().parse_schema(source_text, path)
422 }
423
424 #[allow(clippy::result_large_err)] pub fn parse_and_validate(
428 source_text: impl Into<String>,
429 path: impl AsRef<Path>,
430 ) -> Result<Valid<Self>, WithErrors<Self>> {
431 let mut builder = Schema::builder();
432 Parser::default().parse_into_schema_builder(source_text, path, &mut builder);
433 let (mut schema, mut errors) = builder.build_inner();
434 validation::validate_schema(&mut errors, &mut schema);
435 errors.into_valid_result(schema)
436 }
437
438 pub fn builder() -> SchemaBuilder {
447 SchemaBuilder::new()
448 }
449
450 #[allow(clippy::result_large_err)] pub fn validate(mut self) -> Result<Valid<Self>, WithErrors<Self>> {
452 let mut errors = DiagnosticList::new(self.sources.clone());
453 validation::validate_schema(&mut errors, &mut self);
454 errors.into_valid_result(self)
455 }
456
457 pub fn get_scalar(&self, name: &str) -> Option<&Node<ScalarType>> {
459 if let Some(ExtendedType::Scalar(ty)) = self.types.get(name) {
460 Some(ty)
461 } else {
462 None
463 }
464 }
465
466 pub fn get_object(&self, name: &str) -> Option<&Node<ObjectType>> {
468 if let Some(ExtendedType::Object(ty)) = self.types.get(name) {
469 Some(ty)
470 } else {
471 None
472 }
473 }
474
475 pub fn get_interface(&self, name: &str) -> Option<&Node<InterfaceType>> {
477 if let Some(ExtendedType::Interface(ty)) = self.types.get(name) {
478 Some(ty)
479 } else {
480 None
481 }
482 }
483
484 pub fn get_union(&self, name: &str) -> Option<&Node<UnionType>> {
486 if let Some(ExtendedType::Union(ty)) = self.types.get(name) {
487 Some(ty)
488 } else {
489 None
490 }
491 }
492
493 pub fn get_enum(&self, name: &str) -> Option<&Node<EnumType>> {
495 if let Some(ExtendedType::Enum(ty)) = self.types.get(name) {
496 Some(ty)
497 } else {
498 None
499 }
500 }
501
502 pub fn get_input_object(&self, name: &str) -> Option<&Node<InputObjectType>> {
504 if let Some(ExtendedType::InputObject(ty)) = self.types.get(name) {
505 Some(ty)
506 } else {
507 None
508 }
509 }
510
511 pub fn root_operation(&self, operation_type: ast::OperationType) -> Option<&NamedType> {
513 match operation_type {
514 ast::OperationType::Query => &self.schema_definition.query,
515 ast::OperationType::Mutation => &self.schema_definition.mutation,
516 ast::OperationType::Subscription => &self.schema_definition.subscription,
517 }
518 .as_ref()
519 .map(|component| &component.name)
520 }
521
522 pub fn type_field(
524 &self,
525 type_name: &str,
526 field_name: &str,
527 ) -> Result<&Component<FieldDefinition>, FieldLookupError<'_>> {
528 use ExtendedType::*;
529 let (ty_def_name, ty_def) = self
530 .types
531 .get_key_value(type_name)
532 .ok_or(FieldLookupError::NoSuchType)?;
533 let explicit_field = match ty_def {
534 Object(ty) => ty.fields.get(field_name),
535 Interface(ty) => ty.fields.get(field_name),
536 Scalar(_) | Union(_) | Enum(_) | InputObject(_) => None,
537 };
538 if let Some(def) = explicit_field {
539 return Ok(def);
540 }
541 let meta = MetaFieldDefinitions::get();
542 if field_name == "__typename" && matches!(ty_def, Object(_) | Interface(_) | Union(_)) {
543 return Ok(&meta.__typename);
545 }
546 if self
547 .schema_definition
548 .query
549 .as_ref()
550 .is_some_and(|query_type| query_type == type_name)
551 {
552 match field_name {
553 "__schema" => return Ok(&meta.__schema),
554 "__type" => return Ok(&meta.__type),
555 _ => {}
556 }
557 }
558 Err(FieldLookupError::NoSuchField(ty_def_name, ty_def))
559 }
560
561 pub fn implementers_map(&self) -> HashMap<Name, Implementers> {
570 let mut map = HashMap::<Name, Implementers>::default();
571 for (ty_name, ty) in &self.types {
572 match ty {
573 ExtendedType::Object(def) => {
574 for interface in &def.implements_interfaces {
575 map.entry(interface.name.clone())
576 .or_default()
577 .objects
578 .insert(ty_name.clone());
579 }
580 }
581 ExtendedType::Interface(def) => {
582 for interface in &def.implements_interfaces {
583 map.entry(interface.name.clone())
584 .or_default()
585 .interfaces
586 .insert(ty_name.clone());
587 }
588 }
589 ExtendedType::Scalar(_)
590 | ExtendedType::Union(_)
591 | ExtendedType::Enum(_)
592 | ExtendedType::InputObject(_) => (),
593 };
594 }
595 map
596 }
597
598 pub fn is_subtype(&self, abstract_type: &str, maybe_subtype: &str) -> bool {
603 self.types.get(abstract_type).is_some_and(|ty| match ty {
604 ExtendedType::Interface(_) => self.types.get(maybe_subtype).is_some_and(|ty2| {
605 match ty2 {
606 ExtendedType::Object(def) => &def.implements_interfaces,
607 ExtendedType::Interface(def) => &def.implements_interfaces,
608 ExtendedType::Scalar(_)
609 | ExtendedType::Union(_)
610 | ExtendedType::Enum(_)
611 | ExtendedType::InputObject(_) => return false,
612 }
613 .contains(abstract_type)
614 }),
615 ExtendedType::Union(def) => def.members.contains(maybe_subtype),
616 ExtendedType::Scalar(_)
617 | ExtendedType::Object(_)
618 | ExtendedType::Enum(_)
619 | ExtendedType::InputObject(_) => false,
620 })
621 }
622
623 pub fn is_input_type(&self, ty: &Type) -> bool {
627 match self.types.get(ty.inner_named_type()) {
628 Some(ExtendedType::Scalar(_))
629 | Some(ExtendedType::Enum(_))
630 | Some(ExtendedType::InputObject(_)) => true,
631 Some(ExtendedType::Object(_))
632 | Some(ExtendedType::Interface(_))
633 | Some(ExtendedType::Union(_))
634 | None => false,
635 }
636 }
637
638 pub fn is_output_type(&self, ty: &Type) -> bool {
642 match self.types.get(ty.inner_named_type()) {
643 Some(ExtendedType::Scalar(_))
644 | Some(ExtendedType::Object(_))
645 | Some(ExtendedType::Interface(_))
646 | Some(ExtendedType::Union(_))
647 | Some(ExtendedType::Enum(_)) => true,
648 Some(ExtendedType::InputObject(_)) | None => false,
649 }
650 }
651
652 serialize_method!();
653}
654
655impl SchemaDefinition {
656 pub fn iter_root_operations(
657 &self,
658 ) -> impl Iterator<Item = (ast::OperationType, &ComponentName)> {
659 [
660 (ast::OperationType::Query, &self.query),
661 (ast::OperationType::Mutation, &self.mutation),
662 (ast::OperationType::Subscription, &self.subscription),
663 ]
664 .into_iter()
665 .filter_map(|(ty, maybe_op)| maybe_op.as_ref().map(|op| (ty, op)))
666 }
667
668 pub fn iter_origins(&self) -> impl Iterator<Item = &ComponentOrigin> {
673 self.directives
674 .iter()
675 .map(|dir| &dir.origin)
676 .chain(self.query.iter().map(|name| &name.origin))
677 .chain(self.mutation.iter().map(|name| &name.origin))
678 .chain(self.subscription.iter().map(|name| &name.origin))
679 }
680
681 pub fn extensions(&self) -> IndexSet<&ExtensionId> {
686 self.iter_origins()
687 .filter_map(|origin| origin.extension_id())
688 .collect()
689 }
690}
691
692impl ExtendedType {
693 pub fn name(&self) -> &Name {
694 match self {
695 Self::Scalar(def) => &def.name,
696 Self::Object(def) => &def.name,
697 Self::Interface(def) => &def.name,
698 Self::Union(def) => &def.name,
699 Self::Enum(def) => &def.name,
700 Self::InputObject(def) => &def.name,
701 }
702 }
703
704 pub fn location(&self) -> Option<SourceSpan> {
708 match self {
709 Self::Scalar(ty) => ty.location(),
710 Self::Object(ty) => ty.location(),
711 Self::Interface(ty) => ty.location(),
712 Self::Union(ty) => ty.location(),
713 Self::Enum(ty) => ty.location(),
714 Self::InputObject(ty) => ty.location(),
715 }
716 }
717
718 pub(crate) fn describe(&self) -> &'static str {
719 match self {
720 Self::Scalar(_) => "a scalar type",
721 Self::Object(_) => "an object type",
722 Self::Interface(_) => "an interface type",
723 Self::Union(_) => "a union type",
724 Self::Enum(_) => "an enum type",
725 Self::InputObject(_) => "an input object type",
726 }
727 }
728
729 pub fn is_scalar(&self) -> bool {
730 matches!(self, Self::Scalar(_))
731 }
732
733 pub fn is_object(&self) -> bool {
734 matches!(self, Self::Object(_))
735 }
736
737 pub fn is_interface(&self) -> bool {
738 matches!(self, Self::Interface(_))
739 }
740
741 pub fn is_union(&self) -> bool {
742 matches!(self, Self::Union(_))
743 }
744
745 pub fn is_enum(&self) -> bool {
746 matches!(self, Self::Enum(_))
747 }
748
749 pub fn is_input_object(&self) -> bool {
750 matches!(self, Self::InputObject(_))
751 }
752
753 pub fn as_scalar(&self) -> Option<&ScalarType> {
754 if let Self::Scalar(def) = self {
755 Some(def)
756 } else {
757 None
758 }
759 }
760
761 pub fn as_object(&self) -> Option<&ObjectType> {
762 if let Self::Object(def) = self {
763 Some(def)
764 } else {
765 None
766 }
767 }
768
769 pub fn as_interface(&self) -> Option<&InterfaceType> {
770 if let Self::Interface(def) = self {
771 Some(def)
772 } else {
773 None
774 }
775 }
776
777 pub fn as_union(&self) -> Option<&UnionType> {
778 if let Self::Union(def) = self {
779 Some(def)
780 } else {
781 None
782 }
783 }
784
785 pub fn as_enum(&self) -> Option<&EnumType> {
786 if let Self::Enum(def) = self {
787 Some(def)
788 } else {
789 None
790 }
791 }
792
793 pub fn as_input_object(&self) -> Option<&InputObjectType> {
794 if let Self::InputObject(def) = self {
795 Some(def)
796 } else {
797 None
798 }
799 }
800
801 pub fn is_leaf(&self) -> bool {
806 matches!(self, Self::Scalar(_) | Self::Enum(_))
807 }
808
809 pub fn is_input_type(&self) -> bool {
815 matches!(self, Self::Scalar(_) | Self::Enum(_) | Self::InputObject(_))
816 }
817
818 pub fn is_output_type(&self) -> bool {
824 matches!(
825 self,
826 Self::Scalar(_) | Self::Enum(_) | Self::Object(_) | Self::Interface(_) | Self::Union(_)
827 )
828 }
829
830 pub fn is_built_in(&self) -> bool {
832 match self {
833 Self::Scalar(ty) => ty.is_built_in(),
834 Self::Object(ty) => ty.is_built_in(),
835 Self::Interface(ty) => ty.is_built_in(),
836 Self::Union(ty) => ty.is_built_in(),
837 Self::Enum(ty) => ty.is_built_in(),
838 Self::InputObject(ty) => ty.is_built_in(),
839 }
840 }
841
842 pub fn directives(&self) -> &DirectiveList {
843 match self {
844 Self::Scalar(ty) => &ty.directives,
845 Self::Object(ty) => &ty.directives,
846 Self::Interface(ty) => &ty.directives,
847 Self::Union(ty) => &ty.directives,
848 Self::Enum(ty) => &ty.directives,
849 Self::InputObject(ty) => &ty.directives,
850 }
851 }
852
853 pub fn description(&self) -> Option<&Node<str>> {
854 match self {
855 Self::Scalar(ty) => ty.description.as_ref(),
856 Self::Object(ty) => ty.description.as_ref(),
857 Self::Interface(ty) => ty.description.as_ref(),
858 Self::Union(ty) => ty.description.as_ref(),
859 Self::Enum(ty) => ty.description.as_ref(),
860 Self::InputObject(ty) => ty.description.as_ref(),
861 }
862 }
863
864 pub fn iter_origins(&self) -> impl Iterator<Item = &ComponentOrigin> {
869 match self {
870 Self::Scalar(ty) => Box::new(ty.iter_origins()) as Box<dyn Iterator<Item = _>>,
871 Self::Object(ty) => Box::new(ty.iter_origins()),
872 Self::Interface(ty) => Box::new(ty.iter_origins()),
873 Self::Union(ty) => Box::new(ty.iter_origins()),
874 Self::Enum(ty) => Box::new(ty.iter_origins()),
875 Self::InputObject(ty) => Box::new(ty.iter_origins()),
876 }
877 }
878
879 pub fn extensions(&self) -> IndexSet<&ExtensionId> {
884 self.iter_origins()
885 .filter_map(|origin| origin.extension_id())
886 .collect()
887 }
888
889 serialize_method!();
890}
891
892impl ScalarType {
893 pub fn iter_origins(&self) -> impl Iterator<Item = &ComponentOrigin> {
898 self.directives.iter().map(|dir| &dir.origin)
899 }
900
901 pub fn extensions(&self) -> IndexSet<&ExtensionId> {
906 self.iter_origins()
907 .filter_map(|origin| origin.extension_id())
908 .collect()
909 }
910
911 serialize_method!();
912}
913
914impl ObjectType {
915 pub fn iter_origins(&self) -> impl Iterator<Item = &ComponentOrigin> {
920 self.directives
921 .iter()
922 .map(|dir| &dir.origin)
923 .chain(
924 self.implements_interfaces
925 .iter()
926 .map(|component| &component.origin),
927 )
928 .chain(self.fields.values().map(|field| &field.origin))
929 }
930
931 pub fn extensions(&self) -> IndexSet<&ExtensionId> {
936 self.iter_origins()
937 .filter_map(|origin| origin.extension_id())
938 .collect()
939 }
940
941 serialize_method!();
942}
943
944impl InterfaceType {
945 pub fn iter_origins(&self) -> impl Iterator<Item = &ComponentOrigin> {
950 self.directives
951 .iter()
952 .map(|dir| &dir.origin)
953 .chain(
954 self.implements_interfaces
955 .iter()
956 .map(|component| &component.origin),
957 )
958 .chain(self.fields.values().map(|field| &field.origin))
959 }
960
961 pub fn extensions(&self) -> IndexSet<&ExtensionId> {
966 self.iter_origins()
967 .filter_map(|origin| origin.extension_id())
968 .collect()
969 }
970
971 serialize_method!();
972}
973
974impl UnionType {
975 pub fn iter_origins(&self) -> impl Iterator<Item = &ComponentOrigin> {
980 self.directives
981 .iter()
982 .map(|dir| &dir.origin)
983 .chain(self.members.iter().map(|component| &component.origin))
984 }
985
986 pub fn extensions(&self) -> IndexSet<&ExtensionId> {
991 self.iter_origins()
992 .filter_map(|origin| origin.extension_id())
993 .collect()
994 }
995
996 serialize_method!();
997}
998
999impl EnumType {
1000 pub fn iter_origins(&self) -> impl Iterator<Item = &ComponentOrigin> {
1005 self.directives
1006 .iter()
1007 .map(|dir| &dir.origin)
1008 .chain(self.values.values().map(|value| &value.origin))
1009 }
1010
1011 pub fn extensions(&self) -> IndexSet<&ExtensionId> {
1016 self.iter_origins()
1017 .filter_map(|origin| origin.extension_id())
1018 .collect()
1019 }
1020
1021 serialize_method!();
1022}
1023
1024impl InputObjectType {
1025 pub fn is_one_of(&self) -> bool {
1027 self.directives.get("oneOf").is_some()
1028 }
1029
1030 pub fn iter_origins(&self) -> impl Iterator<Item = &ComponentOrigin> {
1035 self.directives
1036 .iter()
1037 .map(|dir| &dir.origin)
1038 .chain(self.fields.values().map(|field| &field.origin))
1039 }
1040
1041 pub fn extensions(&self) -> IndexSet<&ExtensionId> {
1046 self.iter_origins()
1047 .filter_map(|origin| origin.extension_id())
1048 .collect()
1049 }
1050
1051 serialize_method!();
1052}
1053
1054impl DirectiveList {
1055 pub const fn new() -> Self {
1056 Self(Vec::new())
1057 }
1058
1059 pub fn get_all<'def: 'name, 'name>(
1064 &'def self,
1065 name: &'name str,
1066 ) -> impl Iterator<Item = &'def Component<Directive>> + 'name {
1067 self.0.iter().filter(move |dir| dir.name == name)
1068 }
1069
1070 pub fn get(&self, name: &str) -> Option<&Component<Directive>> {
1075 self.get_all(name).next()
1076 }
1077
1078 pub fn has(&self, name: &str) -> bool {
1080 self.get(name).is_some()
1081 }
1082
1083 pub(crate) fn iter_ast(&self) -> impl Iterator<Item = &Node<ast::Directive>> {
1084 self.0.iter().map(|component| &component.node)
1085 }
1086
1087 pub fn push(&mut self, directive: impl Into<Component<Directive>>) {
1089 self.0.push(directive.into());
1090 }
1091
1092 serialize_method!();
1093}
1094
1095impl std::fmt::Debug for DirectiveList {
1096 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1097 self.0.fmt(f)
1098 }
1099}
1100
1101impl std::ops::Deref for DirectiveList {
1102 type Target = Vec<Component<Directive>>;
1103
1104 fn deref(&self) -> &Self::Target {
1105 &self.0
1106 }
1107}
1108
1109impl std::ops::DerefMut for DirectiveList {
1110 fn deref_mut(&mut self) -> &mut Self::Target {
1111 &mut self.0
1112 }
1113}
1114
1115impl IntoIterator for DirectiveList {
1116 type Item = Component<Directive>;
1117
1118 type IntoIter = std::vec::IntoIter<Component<Directive>>;
1119
1120 fn into_iter(self) -> Self::IntoIter {
1121 self.0.into_iter()
1122 }
1123}
1124
1125impl<'a> IntoIterator for &'a DirectiveList {
1126 type Item = &'a Component<Directive>;
1127
1128 type IntoIter = std::slice::Iter<'a, Component<Directive>>;
1129
1130 fn into_iter(self) -> Self::IntoIter {
1131 self.0.iter()
1132 }
1133}
1134
1135impl<'a> IntoIterator for &'a mut DirectiveList {
1136 type Item = &'a mut Component<Directive>;
1137
1138 type IntoIter = std::slice::IterMut<'a, Component<Directive>>;
1139
1140 fn into_iter(self) -> Self::IntoIter {
1141 self.0.iter_mut()
1142 }
1143}
1144
1145impl<D> FromIterator<D> for DirectiveList
1146where
1147 D: Into<Component<Directive>>,
1148{
1149 fn from_iter<T: IntoIterator<Item = D>>(iter: T) -> Self {
1150 Self(iter.into_iter().map(Into::into).collect())
1151 }
1152}
1153
1154impl Eq for Schema {}
1155
1156impl PartialEq for Schema {
1157 fn eq(&self, other: &Self) -> bool {
1158 let Self {
1159 sources: _, validate_default_values: _, schema_definition,
1162 directive_definitions,
1163 types,
1164 } = self;
1165 *schema_definition == other.schema_definition
1166 && *directive_definitions == other.directive_definitions
1167 && *types == other.types
1168 }
1169}
1170
1171impl Implementers {
1172 pub fn iter(&self) -> impl Iterator<Item = &'_ Name> {
1176 self.objects.iter().chain(&self.interfaces)
1177 }
1178}
1179
1180impl From<Node<ScalarType>> for ExtendedType {
1181 fn from(ty: Node<ScalarType>) -> Self {
1182 Self::Scalar(ty)
1183 }
1184}
1185
1186impl From<Node<ObjectType>> for ExtendedType {
1187 fn from(ty: Node<ObjectType>) -> Self {
1188 Self::Object(ty)
1189 }
1190}
1191
1192impl From<Node<InterfaceType>> for ExtendedType {
1193 fn from(ty: Node<InterfaceType>) -> Self {
1194 Self::Interface(ty)
1195 }
1196}
1197
1198impl From<Node<UnionType>> for ExtendedType {
1199 fn from(ty: Node<UnionType>) -> Self {
1200 Self::Union(ty)
1201 }
1202}
1203
1204impl From<Node<EnumType>> for ExtendedType {
1205 fn from(ty: Node<EnumType>) -> Self {
1206 Self::Enum(ty)
1207 }
1208}
1209
1210impl From<Node<InputObjectType>> for ExtendedType {
1211 fn from(ty: Node<InputObjectType>) -> Self {
1212 Self::InputObject(ty)
1213 }
1214}
1215
1216impl From<ScalarType> for ExtendedType {
1217 fn from(ty: ScalarType) -> Self {
1218 Self::Scalar(ty.into())
1219 }
1220}
1221
1222impl From<ObjectType> for ExtendedType {
1223 fn from(ty: ObjectType) -> Self {
1224 Self::Object(ty.into())
1225 }
1226}
1227
1228impl From<InterfaceType> for ExtendedType {
1229 fn from(ty: InterfaceType) -> Self {
1230 Self::Interface(ty.into())
1231 }
1232}
1233
1234impl From<UnionType> for ExtendedType {
1235 fn from(ty: UnionType) -> Self {
1236 Self::Union(ty.into())
1237 }
1238}
1239
1240impl From<EnumType> for ExtendedType {
1241 fn from(ty: EnumType) -> Self {
1242 Self::Enum(ty.into())
1243 }
1244}
1245
1246impl From<InputObjectType> for ExtendedType {
1247 fn from(ty: InputObjectType) -> Self {
1248 Self::InputObject(ty.into())
1249 }
1250}
1251
1252impl std::fmt::Debug for Schema {
1253 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1254 let Self {
1255 sources,
1256 schema_definition,
1257 directive_definitions,
1258 types,
1259 validate_default_values: _,
1260 } = self;
1261 f.debug_struct("Schema")
1262 .field("sources", sources)
1263 .field("schema_definition", schema_definition)
1264 .field(
1265 "directive_definitions",
1266 &DebugDirectiveDefinitions(directive_definitions),
1267 )
1268 .field("types", &DebugTypes(types))
1269 .finish()
1270 }
1271}
1272
1273struct DebugDirectiveDefinitions<'a>(&'a IndexMap<Name, Node<DirectiveDefinition>>);
1274
1275struct DebugTypes<'a>(&'a IndexMap<Name, ExtendedType>);
1276
1277impl std::fmt::Debug for DebugDirectiveDefinitions<'_> {
1278 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1279 let mut map = f.debug_map();
1280 for (name, def) in self.0 {
1281 if !def.is_built_in() {
1282 map.entry(name, def);
1283 } else {
1284 map.entry(name, &format_args!("built_in_directive!({name:?})"));
1285 }
1286 }
1287 map.finish()
1288 }
1289}
1290
1291impl std::fmt::Debug for DebugTypes<'_> {
1292 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1293 let mut map = f.debug_map();
1294 for (name, def) in self.0 {
1295 if !def.is_built_in() {
1296 map.entry(name, def);
1297 } else {
1298 map.entry(name, &format_args!("built_in_type!({name:?})"));
1299 }
1300 }
1301 map.finish()
1302 }
1303}
1304
1305struct MetaFieldDefinitions {
1306 __typename: Component<FieldDefinition>,
1307 __schema: Component<FieldDefinition>,
1308 __type: Component<FieldDefinition>,
1309}
1310
1311impl MetaFieldDefinitions {
1312 fn get() -> &'static Self {
1313 static DEFS: OnceLock<MetaFieldDefinitions> = OnceLock::new();
1314 DEFS.get_or_init(|| Self {
1315 __typename: Component::new(FieldDefinition {
1317 description: None,
1318 name: name!("__typename"),
1319 arguments: Vec::new(),
1320 ty: ty!(String!),
1321 directives: ast::DirectiveList::new(),
1322 }),
1323 __schema: Component::new(FieldDefinition {
1325 description: None,
1326 name: name!("__schema"),
1327 arguments: Vec::new(),
1328 ty: ty!(__Schema!),
1329 directives: ast::DirectiveList::new(),
1330 }),
1331 __type: Component::new(FieldDefinition {
1333 description: None,
1334 name: name!("__type"),
1335 arguments: vec![InputValueDefinition {
1336 description: None,
1337 name: name!("name"),
1338 ty: ty!(String!).into(),
1339 default_value: None,
1340 directives: ast::DirectiveList::new(),
1341 }
1342 .into()],
1343 ty: ty!(__Type),
1344 directives: ast::DirectiveList::new(),
1345 }),
1346 })
1347 }
1348}