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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
//! Service-related GraphQL types.

use async_graphql_value::Name;

use super::*;

/// A GraphQL file or request string defining a GraphQL service.
///
/// [Reference](https://spec.graphql.org/October2021/#Document).
#[derive(Debug, Clone)]
pub struct ServiceDocument {
    /// The definitions of this document.
    pub definitions: Vec<TypeSystemDefinition>,
}

/// A definition concerning the type system of a GraphQL service.
///
/// [Reference](https://spec.graphql.org/October2021/#TypeSystemDefinition). This enum also covers
/// [extensions](https://spec.graphql.org/October2021/#TypeSystemExtension).
#[derive(Debug, Clone)]
pub enum TypeSystemDefinition {
    /// The definition of the schema of the service.
    Schema(Positioned<SchemaDefinition>),
    /// The definition of a type in the service.
    Type(Positioned<TypeDefinition>),
    /// The definition of a directive in the service.
    Directive(Positioned<DirectiveDefinition>),
}

/// The definition of the schema in a GraphQL service.
///
/// [Reference](https://spec.graphql.org/October2021/#SchemaDefinition). This also covers
/// [extensions](https://spec.graphql.org/October2021/#SchemaExtension).
#[derive(Debug, Clone)]
pub struct SchemaDefinition {
    /// Whether the schema is an extension of another schema.
    pub extend: bool,
    /// The directives of the schema definition.
    pub directives: Vec<Positioned<ConstDirective>>,
    /// The query root. This is always `Some` when the schema is not extended.
    pub query: Option<Positioned<Name>>,
    /// The mutation root, if present.
    pub mutation: Option<Positioned<Name>>,
    /// The subscription root, if present.
    pub subscription: Option<Positioned<Name>>,
}

/// The definition of a type in a GraphQL service.
///
/// [Reference](https://spec.graphql.org/October2021/#TypeDefinition). This also covers
/// [extensions](https://spec.graphql.org/October2021/#TypeExtension).
#[derive(Debug, Clone)]
pub struct TypeDefinition {
    /// Whether the type is an extension of another type.
    pub extend: bool,
    /// The description of the type, if present. This is never present on an
    /// extension type.
    pub description: Option<Positioned<String>>,
    /// The name of the type.
    pub name: Positioned<Name>,
    /// The directives of type definition.
    pub directives: Vec<Positioned<ConstDirective>>,
    /// Which kind of type is being defined; scalar, object, enum, etc.
    pub kind: TypeKind,
}

/// A kind of type; scalar, object, enum, etc.
#[derive(Debug, Clone)]
pub enum TypeKind {
    /// A scalar type.
    Scalar,
    /// An object type.
    Object(ObjectType),
    /// An interface type.
    Interface(InterfaceType),
    /// A union type.
    Union(UnionType),
    /// An enum type.
    Enum(EnumType),
    /// An input object type.
    InputObject(InputObjectType),
}

/// The definition of an object type.
///
/// [Reference](https://spec.graphql.org/October2021/#ObjectType).
#[derive(Debug, Clone)]
pub struct ObjectType {
    /// The interfaces implemented by the object.
    pub implements: Vec<Positioned<Name>>,
    /// The fields of the object type.
    pub fields: Vec<Positioned<FieldDefinition>>,
}

/// The definition of a field inside an object or interface.
///
/// [Reference](https://spec.graphql.org/October2021/#FieldDefinition).
#[derive(Debug, Clone)]
pub struct FieldDefinition {
    /// The description of the field.
    pub description: Option<Positioned<String>>,
    /// The name of the field.
    pub name: Positioned<Name>,
    /// The arguments of the field.
    pub arguments: Vec<Positioned<InputValueDefinition>>,
    /// The type of the field.
    pub ty: Positioned<Type>,
    /// The directives of the field.
    pub directives: Vec<Positioned<ConstDirective>>,
}

/// The definition of an interface type.
///
/// [Reference](https://spec.graphql.org/October2021/#InterfaceType).
#[derive(Debug, Clone)]
pub struct InterfaceType {
    /// The interfaces implemented by the interface.
    pub implements: Vec<Positioned<Name>>,
    /// The fields of the interface type.
    pub fields: Vec<Positioned<FieldDefinition>>,
}

/// The definition of a union type.
///
/// [Reference](https://spec.graphql.org/October2021/#UnionType).
#[derive(Debug, Clone)]
pub struct UnionType {
    /// The member types of the union.
    pub members: Vec<Positioned<Name>>,
}

/// The definition of an enum.
///
/// [Reference](https://spec.graphql.org/October2021/#EnumType).
#[derive(Debug, Clone)]
pub struct EnumType {
    /// The possible values of the enum.
    pub values: Vec<Positioned<EnumValueDefinition>>,
}

/// The definition of a value inside an enum.
///
/// [Reference](https://spec.graphql.org/October2021/#EnumValueDefinition).
#[derive(Debug, Clone)]
pub struct EnumValueDefinition {
    /// The description of the argument.
    pub description: Option<Positioned<String>>,
    /// The value name.
    pub value: Positioned<Name>,
    /// The directives of the enum value.
    pub directives: Vec<Positioned<ConstDirective>>,
}

/// The definition of an input object.
///
/// [Reference](https://spec.graphql.org/October2021/#InputObjectType).
#[derive(Debug, Clone)]
pub struct InputObjectType {
    /// The fields of the input object.
    pub fields: Vec<Positioned<InputValueDefinition>>,
}

/// The definition of an input value inside the arguments of a field.
///
/// [Reference](https://spec.graphql.org/October2021/#InputValueDefinition).
#[derive(Debug, Clone)]
pub struct InputValueDefinition {
    /// The description of the argument.
    pub description: Option<Positioned<String>>,
    /// The name of the argument.
    pub name: Positioned<Name>,
    /// The type of the argument.
    pub ty: Positioned<Type>,
    /// The default value of the argument, if there is one.
    pub default_value: Option<Positioned<ConstValue>>,
    /// The directives of the input value.
    pub directives: Vec<Positioned<ConstDirective>>,
}

/// The definition of a directive in a service.
///
/// [Reference](https://spec.graphql.org/October2021/#DirectiveDefinition).
#[derive(Debug, Clone)]
pub struct DirectiveDefinition {
    /// The description of the directive.
    pub description: Option<Positioned<String>>,
    /// The name of the directive.
    pub name: Positioned<Name>,
    /// The arguments of the directive.
    pub arguments: Vec<Positioned<InputValueDefinition>>,
    /// The locations the directive applies to.
    pub locations: Vec<Positioned<DirectiveLocation>>,
}

/// Where a directive can apply to.
///
/// [Reference](https://spec.graphql.org/October2021/#DirectiveLocation).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DirectiveLocation {
    /// A [query](enum.OperationType.html#variant.Query)
    /// [operation](struct.OperationDefinition.html).
    Query,
    /// A [mutation](enum.OperationType.html#variant.Mutation)
    /// [operation](struct.OperationDefinition.html).
    Mutation,
    /// A [subscription](enum.OperationType.html#variant.Subscription)
    /// [operation](struct.OperationDefinition.html).
    Subscription,
    /// A [field](struct.Field.html).
    Field,
    /// A [fragment definition](struct.FragmentDefinition.html).
    FragmentDefinition,
    /// A [fragment spread](struct.FragmentSpread.html).
    FragmentSpread,
    /// An [inline fragment](struct.InlineFragment.html).
    InlineFragment,
    /// A [schema](struct.Schema.html).
    Schema,
    /// A [scalar](enum.TypeKind.html#variant.Scalar).
    Scalar,
    /// An [object](struct.ObjectType.html).
    Object,
    /// A [field definition](struct.FieldDefinition.html).
    FieldDefinition,
    /// An [input value definition](struct.InputFieldDefinition.html) as the
    /// arguments of a field but not an input object.
    ArgumentDefinition,
    /// An [interface](struct.InterfaceType.html).
    Interface,
    /// A [union](struct.UnionType.html).
    Union,
    /// An [enum](struct.EnumType.html).
    Enum,
    /// A [value on an enum](struct.EnumValueDefinition.html).
    EnumValue,
    /// An [input object](struct.InputObjectType.html).
    InputObject,
    /// An [input value definition](struct.InputValueDefinition.html) on an
    /// input object but not a field.
    InputFieldDefinition,
    /// An [variable definition](struct.VariableDefinition.html).
    VariableDefinition,
}