Skip to main content

cynic_parser/type_system/
definitions.rs

1use crate::AstLookup;
2
3use super::{
4    DefinitionId, Description, Directive, DirectiveDefinition, EnumDefinition,
5    InputObjectDefinition, InterfaceDefinition, ObjectDefinition, ScalarDefinition,
6    SchemaDefinition, TypeSystemId, UnionDefinition,
7    ids::*,
8    iter::{IdReader, Iter},
9};
10
11#[derive(Clone, Copy)]
12pub enum DefinitionRecord {
13    Schema(SchemaDefinitionId),
14    Scalar(ScalarDefinitionId),
15    Object(ObjectDefinitionId),
16    Interface(InterfaceDefinitionId),
17    Union(UnionDefinitionId),
18    Enum(EnumDefinitionId),
19    InputObject(InputObjectDefinitionId),
20    SchemaExtension(SchemaDefinitionId),
21    ScalarExtension(ScalarDefinitionId),
22    ObjectExtension(ObjectDefinitionId),
23    InterfaceExtension(InterfaceDefinitionId),
24    UnionExtension(UnionDefinitionId),
25    EnumExtension(EnumDefinitionId),
26    InputObjectExtension(InputObjectDefinitionId),
27    Directive(DirectiveDefinitionId),
28}
29
30#[derive(Clone, Copy)]
31pub enum Definition<'a> {
32    Schema(SchemaDefinition<'a>),
33    SchemaExtension(SchemaDefinition<'a>),
34    Type(TypeDefinition<'a>),
35    TypeExtension(TypeDefinition<'a>),
36    Directive(DirectiveDefinition<'a>),
37}
38
39impl Definition<'_> {
40    pub fn span(&self) -> crate::Span {
41        match self {
42            Definition::Schema(def) | Definition::SchemaExtension(def) => def.span(),
43            Definition::Type(ty) | Definition::TypeExtension(ty) => ty.span(),
44            Definition::Directive(def) => def.span(),
45        }
46    }
47}
48
49impl<'a> Definition<'a> {
50    pub fn is_schema(&self) -> bool {
51        matches!(self, Definition::Schema(_))
52    }
53
54    pub fn as_schema(self) -> Option<SchemaDefinition<'a>> {
55        match self {
56            Self::Schema(inner) => Some(inner),
57            _ => None,
58        }
59    }
60
61    pub fn is_schema_extension(&self) -> bool {
62        matches!(self, Definition::SchemaExtension(_))
63    }
64
65    pub fn as_schema_extension(self) -> Option<SchemaDefinition<'a>> {
66        match self {
67            Self::SchemaExtension(inner) => Some(inner),
68            _ => None,
69        }
70    }
71
72    pub fn is_type(&self) -> bool {
73        matches!(self, Definition::Type(_))
74    }
75
76    pub fn as_type(self) -> Option<TypeDefinition<'a>> {
77        match self {
78            Self::Type(inner) => Some(inner),
79            _ => None,
80        }
81    }
82
83    pub fn is_type_extension(&self) -> bool {
84        matches!(self, Definition::TypeExtension(_))
85    }
86
87    pub fn as_type_extension(self) -> Option<TypeDefinition<'a>> {
88        match self {
89            Self::TypeExtension(inner) => Some(inner),
90            _ => None,
91        }
92    }
93
94    pub fn is_directive(&self) -> bool {
95        matches!(self, Definition::Directive(_))
96    }
97
98    pub fn as_directive(self) -> Option<DirectiveDefinition<'a>> {
99        match self {
100            Self::Directive(inner) => Some(inner),
101            _ => None,
102        }
103    }
104}
105
106#[derive(Clone, Copy)]
107pub enum TypeDefinition<'a> {
108    Scalar(ScalarDefinition<'a>),
109    Object(ObjectDefinition<'a>),
110    Interface(InterfaceDefinition<'a>),
111    Union(UnionDefinition<'a>),
112    Enum(EnumDefinition<'a>),
113    InputObject(InputObjectDefinition<'a>),
114}
115
116impl<'a> TypeDefinition<'a> {
117    pub fn name(&self) -> &'a str {
118        match self {
119            TypeDefinition::Scalar(inner) => inner.name(),
120            TypeDefinition::Object(inner) => inner.name(),
121            TypeDefinition::Interface(inner) => inner.name(),
122            TypeDefinition::Union(inner) => inner.name(),
123            TypeDefinition::Enum(inner) => inner.name(),
124            TypeDefinition::InputObject(inner) => inner.name(),
125        }
126    }
127
128    pub fn directives(&self) -> Iter<'a, Directive<'a>> {
129        match self {
130            TypeDefinition::Scalar(inner) => inner.directives(),
131            TypeDefinition::Object(inner) => inner.directives(),
132            TypeDefinition::Interface(inner) => inner.directives(),
133            TypeDefinition::Union(inner) => inner.directives(),
134            TypeDefinition::Enum(inner) => inner.directives(),
135            TypeDefinition::InputObject(inner) => inner.directives(),
136        }
137    }
138
139    pub fn span(&self) -> crate::Span {
140        match self {
141            TypeDefinition::Scalar(inner) => inner.span(),
142            TypeDefinition::Object(inner) => inner.span(),
143            TypeDefinition::Interface(inner) => inner.span(),
144            TypeDefinition::Union(inner) => inner.span(),
145            TypeDefinition::Enum(inner) => inner.span(),
146            TypeDefinition::InputObject(inner) => inner.span(),
147        }
148    }
149
150    pub fn description(&self) -> Option<Description<'a>> {
151        match self {
152            TypeDefinition::Scalar(inner) => inner.description(),
153            TypeDefinition::Object(inner) => inner.description(),
154            TypeDefinition::Interface(inner) => inner.description(),
155            TypeDefinition::Union(inner) => inner.description(),
156            TypeDefinition::Enum(inner) => inner.description(),
157            TypeDefinition::InputObject(inner) => inner.description(),
158        }
159    }
160}
161
162impl<'a> TypeDefinition<'a> {
163    pub fn is_scalar(&self) -> bool {
164        matches!(self, TypeDefinition::Scalar(_))
165    }
166
167    pub fn as_scalar(&self) -> Option<ScalarDefinition<'a>> {
168        match self {
169            TypeDefinition::Scalar(inner) => Some(*inner),
170            _ => None,
171        }
172    }
173
174    pub fn is_object(&self) -> bool {
175        matches!(self, TypeDefinition::Object(_))
176    }
177
178    pub fn as_object(&self) -> Option<ObjectDefinition<'a>> {
179        match self {
180            TypeDefinition::Object(inner) => Some(*inner),
181            _ => None,
182        }
183    }
184
185    pub fn is_interface(&self) -> bool {
186        matches!(self, TypeDefinition::Interface(_))
187    }
188
189    pub fn as_interface(&self) -> Option<InterfaceDefinition<'a>> {
190        match self {
191            TypeDefinition::Interface(inner) => Some(*inner),
192            _ => None,
193        }
194    }
195
196    pub fn is_union(&self) -> bool {
197        matches!(self, TypeDefinition::Union(_))
198    }
199
200    pub fn as_union(&self) -> Option<UnionDefinition<'a>> {
201        match self {
202            TypeDefinition::Union(inner) => Some(*inner),
203            _ => None,
204        }
205    }
206
207    pub fn is_enum(&self) -> bool {
208        matches!(self, TypeDefinition::Enum(_))
209    }
210
211    pub fn as_enum(&self) -> Option<EnumDefinition<'a>> {
212        match self {
213            TypeDefinition::Enum(inner) => Some(*inner),
214            _ => None,
215        }
216    }
217
218    pub fn is_input_object(&self) -> bool {
219        matches!(self, TypeDefinition::InputObject(_))
220    }
221
222    pub fn as_input_object(&self) -> Option<InputObjectDefinition<'a>> {
223        match self {
224            TypeDefinition::InputObject(inner) => Some(*inner),
225            _ => None,
226        }
227    }
228}
229
230impl TypeSystemId for DefinitionId {
231    type Reader<'a> = Definition<'a>;
232
233    fn read(self, document: &super::TypeSystemDocument) -> Self::Reader<'_> {
234        match document.lookup(self) {
235            DefinitionRecord::Schema(id) => Definition::Schema(document.read(*id)),
236            DefinitionRecord::Scalar(id) => {
237                Definition::Type(TypeDefinition::Scalar(document.read(*id)))
238            }
239            DefinitionRecord::Object(id) => {
240                Definition::Type(TypeDefinition::Object(document.read(*id)))
241            }
242            DefinitionRecord::Interface(id) => {
243                Definition::Type(TypeDefinition::Interface(document.read(*id)))
244            }
245            DefinitionRecord::Union(id) => {
246                Definition::Type(TypeDefinition::Union(document.read(*id)))
247            }
248            DefinitionRecord::Enum(id) => {
249                Definition::Type(TypeDefinition::Enum(document.read(*id)))
250            }
251            DefinitionRecord::InputObject(id) => {
252                Definition::Type(TypeDefinition::InputObject(document.read(*id)))
253            }
254            DefinitionRecord::SchemaExtension(id) => {
255                Definition::SchemaExtension(document.read(*id))
256            }
257            DefinitionRecord::ScalarExtension(id) => {
258                Definition::TypeExtension(TypeDefinition::Scalar(document.read(*id)))
259            }
260            DefinitionRecord::ObjectExtension(id) => {
261                Definition::TypeExtension(TypeDefinition::Object(document.read(*id)))
262            }
263            DefinitionRecord::InterfaceExtension(id) => {
264                Definition::TypeExtension(TypeDefinition::Interface(document.read(*id)))
265            }
266            DefinitionRecord::UnionExtension(id) => {
267                Definition::TypeExtension(TypeDefinition::Union(document.read(*id)))
268            }
269            DefinitionRecord::EnumExtension(id) => {
270                Definition::TypeExtension(TypeDefinition::Enum(document.read(*id)))
271            }
272            DefinitionRecord::InputObjectExtension(id) => {
273                Definition::TypeExtension(TypeDefinition::InputObject(document.read(*id)))
274            }
275            DefinitionRecord::Directive(id) => Definition::Directive(document.read(*id)),
276        }
277    }
278}
279
280impl IdReader for Definition<'_> {
281    type Id = DefinitionId;
282    type Reader<'a> = Definition<'a>;
283
284    fn new(id: Self::Id, document: &'_ super::TypeSystemDocument) -> Self::Reader<'_> {
285        document.read(id)
286    }
287}