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}