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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
//! Defines the types & results for running an introspection query against
//! a GraphQL server.

#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "Query")]
/// A [GraphQL Introspection Query][1] for Cynic.
///
/// By default this runs a query compatible with the
/// [June 2018 version of the GraphQL specification][2].
///
/// [1]: http://spec.graphql.org/October2021/#sec-Introspection
/// [2]: https://spec.graphql.org/June2018/
pub struct IntrospectionQuery {
    #[cynic(rename = "__schema")]
    /// The schema returned from the query
    pub introspected_schema: IntrospectedSchema,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "__Schema")]
/// The schema returned from a query
pub struct IntrospectedSchema {
    /// The `query` root operation type
    pub query_type: NamedType,
    /// The `mutation` root operation type if any
    pub mutation_type: Option<NamedType>,
    /// The `subscription` root operation type if any
    pub subscription_type: Option<NamedType>,
    /// All the types available in the schema
    pub types: Vec<Type>,
    /// All the directives available in the schema
    pub directives: Vec<Directive>,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "__Directive")]
/// A directive either used in the schema or available to queries
pub struct Directive {
    /// The name of the directive
    pub name: String,
    /// A description of the directive
    pub description: Option<String>,
    /// Any arguments that can be provided to the directive
    pub args: Vec<InputValue>,
    /// The locations where the directive may be used
    pub locations: Vec<DirectiveLocation>,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "__Type")]
/// Details about a type in the schema
pub struct Type {
    /// The kind of type this `Type` is describing
    pub kind: TypeKind,
    /// The name of the `Type`
    ///
    /// This is an `Option` but the use of this struct means it should never
    /// be `None`.
    pub name: Option<String>,
    /// A description of the type
    pub description: Option<String>,
    /// The fields of the type, if it is an object or interface
    #[arguments(includeDeprecated: true)]
    pub fields: Option<Vec<Field>>,
    /// The input fields of the type, if it is an input object
    pub input_fields: Option<Vec<InputValue>>,
    /// Any interfaces this type implements, if it is an object or interface
    pub interfaces: Option<Vec<NamedType>>,
    /// The values this type can be, if it is an enum
    #[arguments(includeDeprecated: true)]
    pub enum_values: Option<Vec<EnumValue>>,
    /// A list of types that can be represented by this type if it is a union,
    /// or the set of types that implement this interface if it is an interface
    pub possible_types: Option<Vec<NamedType>>,
    /// A URL pointing to a specification for this scalar, if there is one
    #[cynic(rename = "specifiedByURL", feature = "2021")]
    pub specified_by_url: Option<String>,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "__EnumValue")]
/// Represents one of the possible values of an enum type
pub struct EnumValue {
    /// The name of the value
    pub name: String,
    /// A description of the value
    pub description: Option<String>,
    /// Whether the value is deprecated and should no longer be used.
    pub is_deprecated: bool,
    /// Optionally provides a reason why this enum value is deprecated
    pub deprecation_reason: Option<String>,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "__Field")]
/// Represents one of the fields of an object or interface type
pub struct Field {
    /// The name of the field
    pub name: String,
    /// A description of the field
    pub description: Option<String>,
    /// A list of arguments this field accepts.
    pub args: Vec<InputValue>,
    /// The type of value returned by this field
    #[cynic(rename = "type")]
    pub ty: FieldType,
    /// Whether this field is deprecated and should no longer be used.
    pub is_deprecated: bool,
    /// Optionally provides a reason why this field is deprecated
    pub deprecation_reason: Option<String>,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "__InputValue")]
/// Represents field and directive arguments as well as the fields of an input object.
pub struct InputValue {
    /// The name of the argument/field
    pub name: String,
    /// A description of the argument/field
    pub description: Option<String>,
    #[cynic(rename = "type")]
    /// The type of this argument/field
    pub ty: FieldType,
    /// An optional default value for this field, represented as a GraphQL literal
    pub default_value: Option<String>,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "__Type")]
/// The type of a [`Field`].
///
/// This may be either a wrapper or a named type, depending on the field in question
pub struct FieldType {
    /// The kind of type this `Type` is describing
    pub kind: TypeKind,
    /// The name of the `Type`
    ///
    /// This is an `Option` but the use of this struct means it should never
    /// be `None`.
    pub name: Option<String>,
    /// If `kind` is [TypeKind::List] or [TypeKind::NonNull] this contains the type
    /// that is wrapped.
    #[cynic(recurse = 6)]
    pub of_type: Option<Box<FieldType>>,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "__Type")]
/// A named type
pub struct NamedType {
    /// The name of the named type.  This shouldn't be null
    pub name: Option<String>,
}

#[derive(cynic::Enum, Clone, Copy, Debug, PartialEq, Eq)]
#[cynic(graphql_type = "__DirectiveLocation")]
#[allow(missing_docs)]
/// A location where a directive can be used
pub enum DirectiveLocation {
    Query,
    Mutation,
    Subscription,
    Field,
    FragmentDefinition,
    FragmentSpread,
    InlineFragment,
    VariableDefinition,
    Schema,
    Scalar,
    Object,
    FieldDefinition,
    ArgumentDefinition,
    Interface,
    Union,
    Enum,
    EnumValue,
    InputObject,
    InputFieldDefinition,
}

#[derive(cynic::Enum, Clone, Copy, Debug)]
#[cynic(graphql_type = "__TypeKind")]
/// The "kind" of a type
pub enum TypeKind {
    /// Represents scalar types such as Int, String, and Boolean.
    Scalar,
    /// Object types represent concrete instantiations of sets of fields.
    Object,
    /// Interfaces are an abstract type where there are common fields declared.
    Interface,
    /// Unions are an abstract type where no common fields are declared.
    Union,
    /// Enums are special scalars that can only have a defined set of values.
    Enum,
    /// Input objects are composite types defined as a list of named input values.
    InputObject,
    /// Lists represent sequences of values in GraphQL. A List type is a type modifier:
    /// it wraps another type instance in the of_type field, which defines the type of
    /// each item in the list.
    List,
    /// GraphQL types are nullable by default.  A Non-Null type is a type modifier: it
    /// wraps another type instance in the ofType field. Non-null types do not allow
    /// null as a response, and indicate required inputs for arguments and input object
    /// fields.
    NonNull,
}

#[cynic::schema("introspection")]
pub(crate) mod schema {}