libgraphql_core/schema/
schema.rs

1use crate::ReadOnlyMap;
2use crate::schema::SchemaBuilder;
3use crate::types::Directive;
4use crate::types::GraphQLType;
5use crate::types::NamedGraphQLTypeRef;
6use std::collections::HashMap;
7
8/// Represents a fully typechecked and immutable GraphQL schema.
9#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
10pub struct Schema {
11    pub(crate) directive_defs: HashMap<String, Directive>,
12    pub(crate) query_type: NamedGraphQLTypeRef,
13    pub(crate) mutation_type: Option<NamedGraphQLTypeRef>,
14    pub(crate) subscription_type: Option<NamedGraphQLTypeRef>,
15    pub(crate) types: HashMap<String, GraphQLType>,
16}
17impl Schema {
18    /// Returns a map from DirectiveName ([`String`]) -> [`Directive`] for *all*
19    /// directives (including built-in GraphQL directives) provided by this
20    /// [`Schema`].
21    ///
22    /// > **⚠️ NOTE:** In addition to directives defined directly in this
23    /// > [`Schema`] this map also includes implicitly-defined, built-in
24    /// > directives like [`Directive::Deprecated`], [`Directive::Include`],
25    /// > [`Directive::Skip`], etc.
26    pub fn all_directives(&self) -> ReadOnlyMap<'_, String, Directive> {
27        ReadOnlyMap::new(&self.directive_defs, None)
28    }
29
30    /// Returns a map from TypeName ([`String`]) -> [`GraphQLType`] for *all*
31    /// types (including built-in GraphQL types) provided by this [`Schema`].
32    ///
33    /// > **⚠️ NOTE:** In addition to types defined directly in this [`Schema`]
34    /// > this map also includes implicitly-defined, built-in types like
35    /// > [`GraphQLType::Bool`], [`GraphQLType::Float`], [`GraphQLType::ID`],
36    /// > etc.
37    pub fn all_types(&self) -> ReadOnlyMap<'_, String, GraphQLType> {
38        ReadOnlyMap::new(&self.types, None)
39    }
40
41    /// Helper function that just delegates to [`SchemaBuilder::new()`].
42    pub fn builder() -> SchemaBuilder {
43        SchemaBuilder::new()
44    }
45
46    /// Returns a map from DirectiveName ([`String`]) -> [`Directive`] for all
47    /// ***non-builtin*** directives defined by this [`Schema`].
48    ///
49    /// > **⚠️ NOTE:** This map does not include any of the built-in directives
50    /// > like [`Directive::Deprecated`], [`Directive::Include`],
51    /// > [`Directive::Skip`], etc. It only includes directives that were
52    /// > defined directly in this [`Schema`].
53    pub fn defined_directives(&self) -> ReadOnlyMap<'_, String, Directive> {
54        ReadOnlyMap::new(
55            &self.directive_defs,
56            Some(|(_, directive)| !directive.is_builtin()),
57        )
58    }
59
60    /// Returns a map from TypeName ([`String`]) -> [`GraphQLType`] for all
61    /// ***non-builtin*** types defined by this [`Schema`].
62    ///
63    /// > **⚠️ NOTE:** This map does not include any of the built-in types like
64    /// > [`GraphQLType::Bool`], [`GraphQLType::Float`], [`GraphQLType::ID`],
65    /// > etc. It only includes types that were defined directly in this
66    /// > [`Schema`].
67    pub fn defined_types(&self) -> ReadOnlyMap<'_, String, GraphQLType> {
68        ReadOnlyMap::new(
69            &self.types,
70            Some(|(_, graphql_type)| !graphql_type.is_builtin()),
71        )
72    }
73
74    /// Returns this [`Schema`]'s Mutation root operation type (if one was
75    /// defined).
76    ///
77    /// > **⚠️ NOTE:** It is ***strongly*** recommended that you use
78    /// > [`Schema::mutation_type()`] in favor of looking for an
79    /// > [`ObjectType`](crate::types::ObjectType) whose name is `"Mutation"`.
80    /// > GraphQL [defines an object type named "Mutation" as the _default_
81    /// > Mutation type ](https://spec.graphql.org/October2021/#sec-Root-Operation-Types.Default-Root-Operation-Type-Names),
82    /// > but it is aslo [possible to override this default
83    /// > ](https://spec.graphql.org/October2021/#RootOperationTypeDefinition) and
84    /// > use a differently-named [`ObjectType`](crate::types::ObjectType)
85    /// > instead. [`Schema::mutation_type()`] factors in any such override and
86    /// > will return the _correct_ [`ObjectType`](crate::types::ObjectType) for
87    /// > this schema.
88    pub fn mutation_type(&self) -> Option<&GraphQLType> {
89        self.mutation_type.as_ref().map(|named_ref| {
90            named_ref.deref(self)
91                .expect("type is present in schema")
92        })
93    }
94
95    /// Returns this [`Schema`]'s Query root operation type.
96    //
97    /// > **⚠️ NOTE**: It is ***strongly*** recommended that you use
98    /// > [`Schema::query_type()`] in favor of looking for an
99    /// > [`ObjectType`](crate::types::ObjectType) whose name is `"Query"`.
100    /// > GraphQL [defines an object type named "Query" as the _default_ Query
101    /// > type](https://spec.graphql.org/October2021/#sec-Root-Operation-Types.Default-Root-Operation-Type-Names),
102    /// > but it is aslo [possible to override this default
103    /// > ](https://spec.graphql.org/October2021/#RootOperationTypeDefinition) and
104    /// > use a differently-named [`ObjectType`](crate::types::ObjectType)
105    /// > instead. [`Schema::query_type()`] factors in any such override and will
106    /// > return the _correct_ [`ObjectType`](crate::types::ObjectType) for this
107    /// > schema.
108    pub fn query_type(&self) -> &GraphQLType {
109        self.query_type.deref(self)
110            .expect("type is present in schema")
111    }
112
113    /// Returns this [`Schema`]'s Subscription root operation type.
114    //
115    /// > **⚠️ NOTE**: It is ***strongly*** recommended that you use
116    /// > [`Schema::subscription_type()`] in favor of looking for an
117    /// > [`ObjectType`](crate::types::ObjectType) whose name is `"Subscription"`.
118    /// > GraphQL [defines an object type named "Subscription" as the _default_
119    /// > Subscription type](https://spec.graphql.org/October2021/#sec-Root-Operation-Types.Default-Root-Operation-Type-Names),
120    /// > but it is aslo [possible to override this default
121    /// > ](https://spec.graphql.org/October2021/#RootOperationTypeDefinition) and
122    /// > use a differently-named [`ObjectType`](crate::types::ObjectType)
123    /// > instead. [`Schema::subscription_type()`] factors in any such override
124    /// > and will return the _correct_ [`ObjectType`](crate::types::ObjectType)
125    /// > for this schema.
126    pub fn subscription_type(&self) -> Option<&GraphQLType> {
127        self.subscription_type.as_ref().map(|named_ref| {
128            named_ref.deref(self)
129                .expect("type is present in schema")
130        })
131    }
132}