1use crate::{Path, Identifier, PathSegment, Mutability};
2use crate::prelude::*;
3
4#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
5pub struct Type {
7 pub path: Path,
9 pub length: Option<usize>,
12}
13
14impl Type {
16 pub fn mutable_reference(type_: impl Into<Type>) -> Self {
18 PathSegment::new(Identifier::mutable_reference(), type_.into()).into()
19 }
20
21 pub fn reference(mutability: Mutability, type_: impl Into<Type>) -> Self {
23 PathSegment::new(Identifier::reference(mutability), type_.into()).into()
24 }
25
26 pub fn constant_reference(type_: impl Into<Type>) -> Self {
28 PathSegment::new(Identifier::constant_reference(), type_.into()).into()
29 }
30
31 pub fn slice(type_: impl Into<Type>) -> Self {
33 PathSegment::new(Identifier::slice(), type_.into()).into()
34 }
35
36 pub fn array(type_: impl Into<Type>, length: usize) -> Self {
38 let path = Path::from(PathSegment::new(Identifier::array(), type_.into()));
39 let length = Some(length);
40 Self { path, length }
41 }
42
43 pub fn vector(type_: impl Into<Type>) -> Self {
45 Path::from(PathSegment::new(Identifier::vector(), type_.into())).into()
46 }
47
48 pub fn union(types: Vec<Type>) -> Self {
50 Path::from(PathSegment::new(Identifier::union(), types)).into()
51 }
52
53 pub fn variadic(type_: impl Into<Type>) -> Self {
55 Path::from(PathSegment::new(Identifier::variadic(), type_.into())).into()
56 }
57
58 pub fn tuple(types: Vec<Type>) -> Self {
60 Path::from(PathSegment::new(Identifier::tuple(), types)).into()
61 }
62
63 pub fn option(type_: impl Into<Type>) -> Self {
65 Path::from(PathSegment::new(Identifier::option(), type_.into())).into()
66 }
67
68 pub fn opaque() -> Self {
70 Identifier::opaque().into()
71 }
72
73 pub fn boolean() -> Self {
75 Identifier::boolean().into()
76 }
77
78 pub fn character() -> Self {
80 Identifier::character().into()
81 }
82
83 pub fn i8() -> Self {
85 Identifier::i8().into()
86 }
87
88 pub fn i16() -> Self {
90 Identifier::i16().into()
91 }
92
93 pub fn i32() -> Self {
95 Identifier::i32().into()
96 }
97
98 pub fn i64() -> Self {
100 Identifier::i64().into()
101 }
102
103 pub fn i128() -> Self {
105 Identifier::i128().into()
106 }
107
108 pub fn isize() -> Self {
110 Identifier::isize().into()
111 }
112
113 pub fn u8() -> Self {
115 Identifier::u8().into()
116 }
117
118 pub fn u16() -> Self {
120 Identifier::u16().into()
121 }
122
123 pub fn u32() -> Self {
125 Identifier::u32().into()
126 }
127
128 pub fn u64() -> Self {
130 Identifier::u64().into()
131 }
132
133 pub fn u128() -> Self {
135 Identifier::u128().into()
136 }
137
138 pub fn usize() -> Self {
140 Identifier::usize().into()
141 }
142
143 pub fn f16() -> Self {
145 Identifier::f16().into()
146 }
147
148 pub fn f32() -> Self {
150 Identifier::f32().into()
151 }
152
153 pub fn f64() -> Self {
155 Identifier::f64().into()
156 }
157
158 pub fn f128() -> Self {
160 Identifier::f128().into()
161 }
162
163 pub fn string() -> Self {
165 Identifier::string().into()
166 }
167}
168
169impl Default for Type {
170 fn default() -> Self {
171 Self::opaque()
172 }
173}
174
175impl Type {
176 pub fn is_primitive(&self) -> bool {
178 self.is_boolean()
179 || self.is_character()
180 || self.is_float()
181 || self.is_integer()
182 || self.is_unsigned_integer()
183 }
184
185 pub fn is<T: Into<Self>>(&self, t: T) -> bool {
186 self == &t.into()
187 }
188
189 pub fn is_mutable_reference(&self) -> bool {
191 self.path.last().identifier == Identifier::mutable_reference()
192 }
193
194 pub fn is_boolean(&self) -> bool {
196 self.is(Self::boolean())
197 }
198
199 pub fn is_character(&self) -> bool {
201 self.is(Self::character())
202 }
203
204 pub fn is_number(&self) -> bool {
206 self.is_integer() || self.is_float()
207 }
208
209 pub fn is_integer(&self) -> bool {
211 self.is(Self::i8()) || self.is(Self::i16()) || self.is(Self::i32()) || self.is(Self::i64()) || self.is(Self::i128())
212 }
213
214 pub fn is_unsigned_integer(&self) -> bool {
216 self.is(Self::u8()) || self.is(Self::u16()) || self.is(Self::u32()) || self.is(Self::u64()) || self.is(Self::u128())
217 }
218
219 pub fn is_float(&self) -> bool {
221 self.is(Self::f32()) || self.is(Self::f64()) || self.is(Self::f128())
222 }
223
224 pub fn is_tuple(&self) -> bool {
226 self.path.last().identifier == Identifier::tuple()
227 }
228
229 pub fn is_vector(&self) -> bool {
231 self.path.last().identifier == Identifier::vector()
232 }
233
234 pub fn is_string(&self) -> bool {
236 self.is(Self::string())
237 }
238}
239
240impl From<PathSegment> for Type {
241 fn from(path_segment: PathSegment) -> Self {
242 Path::from(path_segment).into()
243 }
244}
245
246impl From<&str> for Type {
247 fn from(value: &str) -> Self {
248 Path::from(value).into()
249 }
250}
251
252impl From<Identifier> for Type {
253 fn from(identifier: Identifier) -> Self {
254 Path::from(identifier).into()
255 }
256}
257
258impl From<Path> for Type {
259 fn from(path: Path) -> Self {
260 let length = None;
261 Self { path, length }
262 }
263}
264
265impl std::fmt::Display for Type {
266 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
267 f.write_str(&self.path.to_string())
268 }
269}