1use std::collections::HashMap;
2
3#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq)]
4pub enum PrimitiveType {
5 Bool, I8,
7 U8,
8 I16,
9 U16,
10 I32,
11 U32, I64,
13 U64,
14 I128,
15 U128,
16 Usize,
17 Isize,
18 F32,
19 F64,
20}
21
22impl PrimitiveType {
23 pub fn char() -> Self {
24 Self::U32
25 }
26
27 pub fn is_float(&self) -> bool {
28 matches!(self, Self::F32 | Self::F64)
29 }
30
31 pub fn is_integer(&self) -> bool {
32 !self.is_float() && self != &Self::Bool
33 }
34
35 pub fn is_signed(&self) -> bool {
36 matches!(
37 self,
38 Self::I8 | Self::I16 | Self::I32 | Self::I64 | Self::I128 | Self::Isize
39 )
40 }
41
42 pub fn is_unsigned(&self) -> bool {
43 matches!(
44 self,
45 Self::U8 | Self::U16 | Self::U32 | Self::U64 | Self::U128 | Self::Usize
46 )
47 }
48
49 pub fn width(&self) -> usize {
50 match self {
51 PrimitiveType::Bool => 1,
52 PrimitiveType::I8 | PrimitiveType::U8 => 8,
53 PrimitiveType::I16 | PrimitiveType::U16 => 16,
54 PrimitiveType::I32 | PrimitiveType::U32 => 32,
55 PrimitiveType::I64 | PrimitiveType::U64 => 64,
56 PrimitiveType::I128 | PrimitiveType::U128 => 128,
57 PrimitiveType::Usize | PrimitiveType::Isize => 64,
59 PrimitiveType::F32 => 32,
60 PrimitiveType::F64 => 64,
61 }
62 }
63}
64
65impl std::fmt::Display for PrimitiveType {
66 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67 write!(f, "{}", format!("{self:?}").to_ascii_lowercase())
69 }
70}
71
72#[derive(Debug, Clone, PartialEq)]
73pub enum TypeDecorators {
74 Const,
76 Array,
78 Reference,
79 Pointer,
80 SizedArray(usize),
81}
82
83mod serde_type_decorators {
84 use super::*;
85 struct Visitor;
86
87 impl serde::de::Visitor<'_> for Visitor {
88 type Value = TypeDecorators;
89
90 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
91 formatter.write_str("Const, Unigned, Array, Reference, Pointer...")
92 }
93
94 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
95 where
96 E: serde::de::Error,
97 {
98 match v {
99 "Const" => Ok(TypeDecorators::Const),
100 "Array" => Ok(TypeDecorators::Array),
101 "Reference" => Ok(TypeDecorators::Reference),
102 "Pointer" => Ok(TypeDecorators::Pointer),
103 a => a
104 .parse::<usize>()
105 .map(TypeDecorators::SizedArray)
106 .map_err(E::custom),
107 }
108 }
109 }
110
111 impl serde::Serialize for TypeDecorators {
112 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
113 where
114 S: serde::Serializer,
115 {
116 match self {
117 TypeDecorators::Const => serializer.serialize_str("Const"),
118 TypeDecorators::Array => serializer.serialize_str("Array"),
119 TypeDecorators::Reference => serializer.serialize_str("Reference"),
120 TypeDecorators::Pointer => serializer.serialize_str("Pointer"),
121 TypeDecorators::SizedArray(v) => serializer.serialize_str(&format!("Array {v}")),
122 }
123 }
124 }
125
126 impl<'de> serde::Deserialize<'de> for TypeDecorators {
127 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
128 where
129 D: serde::Deserializer<'de>,
130 {
131 deserializer.deserialize_str(Visitor)
132 }
133 }
134}
135
136#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq)]
137pub struct ComplexType {
138 #[serde(default)]
140 #[serde(skip_serializing_if = "Vec::is_empty")]
141 pub decorators: Vec<TypeDecorators>,
142 #[serde(rename = "type")]
143 pub ty: String,
144}
145
146impl ComplexType {
147 pub fn no_decorators(ty: String) -> Self {
148 Self {
149 decorators: Vec::new(),
150 ty,
151 }
152 }
153
154 pub fn string() -> Self {
155 Self {
156 decorators: vec![TypeDecorators::Array],
157 ty: "u8".into(),
158 }
159 }
160}
161
162impl std::fmt::Display for ComplexType {
163 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
164 for dec in &self.decorators {
165 match dec {
166 TypeDecorators::Const => write!(f, "const "),
167 TypeDecorators::Array => write!(f, "[] "),
168 TypeDecorators::Reference => write!(f, "& "),
169 TypeDecorators::Pointer => write!(f, "* "),
170 TypeDecorators::SizedArray(s) => write!(f, "[{s}] "),
171 }?;
172 }
173
174 write!(f, "{}", self.ty)
175 }
176}
177
178#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq)]
179pub enum TypeDefine {
180 Primitive(PrimitiveType),
181 Complex(ComplexType),
182}
183
184impl TypeDefine {
185 #[must_use]
189 pub fn is_primitive(&self) -> bool {
190 matches!(self, Self::Primitive(..))
191 }
192
193 #[must_use]
197 pub fn is_complex(&self) -> bool {
198 matches!(self, Self::Complex(..))
199 }
200
201 pub fn as_primitive(&self) -> Option<&PrimitiveType> {
202 if let Self::Primitive(v) = self {
203 Some(v)
204 } else {
205 None
206 }
207 }
208}
209
210impl std::fmt::Display for TypeDefine {
211 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
212 match self {
213 TypeDefine::Primitive(ty) => write!(f, "{}", ty),
214 TypeDefine::Complex(ty) => write!(f, "{}", ty),
215 }
216 }
217}
218
219impl From<ComplexType> for TypeDefine {
220 fn from(v: ComplexType) -> Self {
221 Self::Complex(v)
222 }
223}
224
225impl From<PrimitiveType> for TypeDefine {
226 fn from(v: PrimitiveType) -> Self {
227 Self::Primitive(v)
228 }
229}
230
231impl TryFrom<TypeDefine> for PrimitiveType {
232 type Error = TypeDefine;
233
234 fn try_from(value: TypeDefine) -> Result<Self, Self::Error> {
235 match value {
236 TypeDefine::Primitive(p) => Ok(p),
237 TypeDefine::Complex(_) => Err(value),
238 }
239 }
240}
241
242impl TryFrom<TypeDefine> for ComplexType {
243 type Error = TypeDefine;
244
245 fn try_from(value: TypeDefine) -> Result<Self, Self::Error> {
246 match value {
247 TypeDefine::Primitive(_) => Err(value),
248 TypeDefine::Complex(c) => Ok(c),
249 }
250 }
251}
252
253impl PartialEq<PrimitiveType> for TypeDefine {
254 fn eq(&self, other: &PrimitiveType) -> bool {
255 match self {
256 TypeDefine::Primitive(s) => s == other,
257 TypeDefine::Complex(_) => false,
258 }
259 }
260}
261
262#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq)]
263pub enum Type {
264 Template(Template),
265 Primitive(PrimitiveType),
266 Custom(String),
267}
268
269impl From<Template> for Type {
270 fn from(v: Template) -> Self {
271 Self::Template(v)
272 }
273}
274
275impl From<PrimitiveType> for Type {
276 fn from(v: PrimitiveType) -> Self {
277 Self::Primitive(v)
278 }
279}
280
281impl From<String> for Type {
282 fn from(v: String) -> Self {
283 Self::Custom(v)
284 }
285}
286
287#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq)]
288pub struct Template {
289 pub name: String,
290 pub generics: HashMap<String, Type>,
291}
292
293impl Template {
294 pub fn new<I>(name: I, generics: HashMap<String, Type>) -> Self
295 where
296 I: Into<String>,
297 {
298 Self {
299 name: name.into(),
300 generics,
301 }
302 }
303
304 pub fn reference(to: Type) -> Self {
305 Self::new("&", std::iter::once(("T".into(), to)).collect())
306 }
307}