cynic_parser/type_system/
types.rs1use crate::{
2 common::{TypeWrappers, TypeWrappersIter, WrappingType},
3 type_system::ids::TypeId,
4 AstLookup, Span,
5};
6
7use super::{iter::Iter, Definition, ReadContext, StringId, TypeDefinition, TypeSystemId};
8
9pub struct TypeRecord {
10 pub name: StringId,
11 pub name_start: usize,
12 pub wrappers: TypeWrappers,
13 pub span: Span,
14}
15
16#[derive(Clone, Copy)]
17pub struct Type<'a>(ReadContext<'a, TypeId>);
18
19impl PartialEq for Type<'_> {
20 fn eq(&self, other: &Self) -> bool {
21 self.name() == other.name() && self.wrappers().eq(other.wrappers())
22 }
23}
24
25impl Eq for Type<'_> {}
26
27impl<'a> Type<'a> {
28 pub fn name(&self) -> &'a str {
29 self.0
30 .document
31 .lookup(self.0.document.lookup(self.0.id).name)
32 }
33
34 pub fn name_span(&self) -> Span {
36 let record = self.0.document.lookup(self.0.id);
37
38 Span::new(
39 record.name_start,
40 record.name_start + self.0.document.lookup(record.name).len(),
41 )
42 }
43
44 pub fn is_list(&self) -> bool {
45 self.wrappers().any(|wrapper| wrapper == WrappingType::List)
46 }
47
48 pub fn is_non_null(&self) -> bool {
49 self.wrappers().next() == Some(WrappingType::NonNull)
50 }
51
52 pub fn span(&self) -> Span {
54 self.0.document.lookup(self.0.id).span
55 }
56
57 pub fn wrappers(&self) -> TypeWrappersIter {
59 self.0.document.lookup(self.0.id).wrappers.iter()
60 }
61
62 pub fn definitions(&self) -> NamedTypeDefinitions<'a> {
67 let document = self.0.document;
68 NamedTypeDefinitions {
69 name: self.name(),
70 iter: document.definitions(),
71 }
72 }
73}
74
75impl std::fmt::Display for Type<'_> {
76 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77 let ast = &self.0.document;
78
79 let TypeRecord { name, wrappers, .. } = ast.lookup(self.0.id);
80
81 let wrappers = wrappers.iter().collect::<Vec<_>>();
82 for wrapping in &wrappers {
83 if let WrappingType::List = wrapping {
84 write!(f, "[")?;
85 }
86 }
87 write!(f, "{}", ast.lookup(*name))?;
88 for wrapping in wrappers.iter().rev() {
89 match wrapping {
90 WrappingType::NonNull => write!(f, "!")?,
91 WrappingType::List => write!(f, "]")?,
92 }
93 }
94
95 Ok(())
96 }
97}
98
99impl std::fmt::Debug for Type<'_> {
100 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 f.debug_tuple("Type").field(&self.to_string()).finish()
102 }
103}
104
105impl TypeSystemId for TypeId {
106 type Reader<'a> = Type<'a>;
107
108 fn read(self, document: &super::TypeSystemDocument) -> Self::Reader<'_> {
109 Type(ReadContext { id: self, document })
110 }
111}
112
113impl<'a> From<ReadContext<'a, TypeId>> for Type<'a> {
114 fn from(value: ReadContext<'a, TypeId>) -> Self {
115 Self(value)
116 }
117}
118
119#[derive(Clone)]
124pub struct NamedTypeDefinitions<'a> {
125 name: &'a str,
126 iter: Iter<'a, Definition<'a>>,
127}
128
129pub enum NamedTypeDefinition<'a> {
131 Definition(TypeDefinition<'a>),
132 Extension(TypeDefinition<'a>),
133}
134
135impl<'a> Iterator for NamedTypeDefinitions<'a> {
136 type Item = NamedTypeDefinition<'a>;
137
138 fn next(&mut self) -> Option<Self::Item> {
139 loop {
140 match self.iter.next()? {
141 Definition::Type(type_definition) if type_definition.name() == self.name => {
142 return Some(NamedTypeDefinition::Definition(type_definition))
143 }
144 Definition::TypeExtension(type_definition)
145 if type_definition.name() == self.name =>
146 {
147 return Some(NamedTypeDefinition::Extension(type_definition))
148 }
149 _ => continue,
150 }
151 }
152 }
153}