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