cynic_introspection/query.rs
1//! Defines the types & results for running an introspection query against
2//! a GraphQL server.
3
4#[derive(cynic::QueryFragment, Debug)]
5#[cynic(graphql_type = "Query")]
6/// A [GraphQL Introspection Query][1] for Cynic.
7///
8/// By default this runs a query compatible with the
9/// [June 2018 version of the GraphQL specification][2].
10///
11/// [1]: http://spec.graphql.org/October2021/#sec-Introspection
12/// [2]: https://spec.graphql.org/June2018/
13pub struct IntrospectionQuery {
14 #[cynic(rename = "__schema")]
15 /// The schema returned from the query
16 pub introspected_schema: Option<IntrospectedSchema>,
17}
18
19#[derive(cynic::QueryFragment, Debug)]
20#[cynic(graphql_type = "__Schema")]
21/// The schema returned from a query
22pub struct IntrospectedSchema {
23 /// The `query` root operation type
24 pub query_type: NamedType,
25 /// The `mutation` root operation type if any
26 pub mutation_type: Option<NamedType>,
27 /// The `subscription` root operation type if any
28 pub subscription_type: Option<NamedType>,
29 /// All the types available in the schema
30 pub types: Vec<Type>,
31 /// All the directives available in the schema
32 pub directives: Vec<Directive>,
33}
34
35#[derive(cynic::QueryFragment, Debug)]
36#[cynic(graphql_type = "__Directive")]
37/// A directive either used in the schema or available to queries
38pub struct Directive {
39 /// The name of the directive
40 pub name: String,
41 /// A description of the directive
42 pub description: Option<String>,
43 /// Any arguments that can be provided to the directive
44 pub args: Vec<InputValue>,
45 /// The locations where the directive may be used
46 pub locations: Vec<DirectiveLocation>,
47 /// Whether the directive is repeatable or not
48 #[cynic(feature = "2021")]
49 pub is_repeatable: bool,
50}
51
52#[derive(cynic::QueryFragment, Debug)]
53#[cynic(graphql_type = "__Type")]
54/// Details about a type in the schema
55pub struct Type {
56 /// The kind of type this `Type` is describing
57 pub kind: TypeKind,
58 /// The name of the `Type`
59 ///
60 /// This is an `Option` but the use of this struct means it should never
61 /// be `None`.
62 pub name: Option<String>,
63 /// A description of the type
64 pub description: Option<String>,
65 /// The fields of the type, if it is an object or interface
66 #[arguments(includeDeprecated: true)]
67 pub fields: Option<Vec<Field>>,
68 /// The input fields of the type, if it is an input object
69 pub input_fields: Option<Vec<InputValue>>,
70 /// Any interfaces this type implements, if it is an object or interface
71 pub interfaces: Option<Vec<NamedType>>,
72 /// The values this type can be, if it is an enum
73 #[arguments(includeDeprecated: true)]
74 pub enum_values: Option<Vec<EnumValue>>,
75 /// A list of types that can be represented by this type if it is a union,
76 /// or the set of types that implement this interface if it is an interface
77 pub possible_types: Option<Vec<NamedType>>,
78 /// A URL pointing to a specification for this scalar, if there is one
79 #[cynic(rename = "specifiedByURL", feature = "2021")]
80 pub specified_by_url: Option<String>,
81}
82
83#[derive(cynic::QueryFragment, Debug)]
84#[cynic(graphql_type = "__EnumValue")]
85/// Represents one of the possible values of an enum type
86pub struct EnumValue {
87 /// The name of the value
88 pub name: String,
89 /// A description of the value
90 pub description: Option<String>,
91 /// Whether the value is deprecated and should no longer be used.
92 pub is_deprecated: bool,
93 /// Optionally provides a reason why this enum value is deprecated
94 pub deprecation_reason: Option<String>,
95}
96
97#[derive(cynic::QueryFragment, Debug)]
98#[cynic(graphql_type = "__Field")]
99/// Represents one of the fields of an object or interface type
100pub struct Field {
101 /// The name of the field
102 pub name: String,
103 /// A description of the field
104 pub description: Option<String>,
105 /// A list of arguments this field accepts.
106 pub args: Vec<InputValue>,
107 /// The type of value returned by this field
108 #[cynic(rename = "type")]
109 pub ty: FieldType,
110 /// Whether this field is deprecated and should no longer be used.
111 pub is_deprecated: bool,
112 /// Optionally provides a reason why this field is deprecated
113 pub deprecation_reason: Option<String>,
114}
115
116#[derive(cynic::QueryFragment, Debug)]
117#[cynic(graphql_type = "__InputValue")]
118/// Represents field and directive arguments as well as the fields of an input object.
119pub struct InputValue {
120 /// The name of the argument/field
121 pub name: String,
122 /// A description of the argument/field
123 pub description: Option<String>,
124 #[cynic(rename = "type")]
125 /// The type of this argument/field
126 pub ty: FieldType,
127 /// An optional default value for this field, represented as a GraphQL literal
128 pub default_value: Option<String>,
129}
130
131#[derive(cynic::QueryFragment, Debug)]
132#[cynic(graphql_type = "__Type")]
133/// The type of a [`Field`].
134///
135/// This may be either a wrapper or a named type, depending on the field in question
136pub struct FieldType {
137 /// The kind of type this `Type` is describing
138 pub kind: TypeKind,
139 /// The name of the `Type`
140 ///
141 /// This is an `Option` but the use of this struct means it should never
142 /// be `None`.
143 pub name: Option<String>,
144 /// If `kind` is [TypeKind::List] or [TypeKind::NonNull] this contains the type
145 /// that is wrapped.
146 #[cynic(recurse = 6)]
147 pub of_type: Option<Box<FieldType>>,
148}
149
150#[derive(cynic::QueryFragment, Debug)]
151#[cynic(graphql_type = "__Type")]
152/// A named type
153pub struct NamedType {
154 /// The name of the named type. This shouldn't be null
155 pub name: Option<String>,
156}
157
158#[derive(cynic::Enum, Clone, Copy, Debug, PartialEq, Eq)]
159#[cynic(graphql_type = "__DirectiveLocation")]
160#[allow(missing_docs)]
161/// A location where a directive can be used
162pub enum DirectiveLocation {
163 Query,
164 Mutation,
165 Subscription,
166 Field,
167 FragmentDefinition,
168 FragmentSpread,
169 InlineFragment,
170 VariableDefinition,
171 Schema,
172 Scalar,
173 Object,
174 FieldDefinition,
175 ArgumentDefinition,
176 Interface,
177 Union,
178 Enum,
179 EnumValue,
180 InputObject,
181 InputFieldDefinition,
182}
183
184#[derive(cynic::Enum, Clone, Copy, Debug)]
185#[cynic(graphql_type = "__TypeKind")]
186/// The "kind" of a type
187pub enum TypeKind {
188 /// Represents scalar types such as Int, String, and Boolean.
189 Scalar,
190 /// Object types represent concrete instantiations of sets of fields.
191 Object,
192 /// Interfaces are an abstract type where there are common fields declared.
193 Interface,
194 /// Unions are an abstract type where no common fields are declared.
195 Union,
196 /// Enums are special scalars that can only have a defined set of values.
197 Enum,
198 /// Input objects are composite types defined as a list of named input values.
199 InputObject,
200 /// Lists represent sequences of values in GraphQL. A List type is a type modifier:
201 /// it wraps another type instance in the of_type field, which defines the type of
202 /// each item in the list.
203 List,
204 /// GraphQL types are nullable by default. A Non-Null type is a type modifier: it
205 /// wraps another type instance in the ofType field. Non-null types do not allow
206 /// null as a response, and indicate required inputs for arguments and input object
207 /// fields.
208 NonNull,
209}
210
211#[cynic::schema("introspection")]
212pub(crate) mod schema {}
213
214#[cfg(test)]
215mod tests {
216 use super::*;
217
218 #[test]
219 fn snapshot_test_query() {
220 use cynic::QueryBuilder;
221
222 let operation = IntrospectionQuery::build(());
223
224 insta::assert_snapshot!(operation.query);
225 }
226}