1use super::{FunctionName, ValueName};
5use crate::ast::{self, GetName};
6#[cfg(feature = "codec")]
7use serde::{Deserialize, Serialize};
8use std::collections::HashMap;
9use std::fmt::Display;
10
11pub trait TypeAttributes {
14 fn get_attribute_index(&self, attr_name: &ValueName) -> Option<u32>;
16 fn get_attribute_type(&self, attr_name: &ValueName) -> Option<Type>;
18 fn get_method(&self, method_name: String) -> Option<FunctionName>;
20 fn is_attribute(&self, name: &ValueName) -> bool;
22 fn is_method(&self, name: String) -> bool;
24}
25
26#[derive(Debug, Clone, Eq, Hash, PartialEq)]
28#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
29pub struct TypeName(String);
30
31impl GetName for TypeName {
32 fn name(&self) -> String {
33 self.0.clone()
34 }
35}
36
37impl From<String> for TypeName {
38 fn from(value: String) -> Self {
39 Self(value)
40 }
41}
42
43impl Display for TypeName {
44 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45 write!(f, "{}", self.0.clone())
46 }
47}
48
49#[derive(Debug, Clone, Eq, PartialEq)]
55#[cfg_attr(
56 feature = "codec",
57 derive(Serialize, Deserialize),
58 serde(tag = "type", content = "content")
59)]
60pub enum Type {
61 Primitive(PrimitiveTypes),
62 Struct(StructTypes),
63 Array(Box<Self>, u32),
64}
65
66impl Type {
67 #[must_use]
69 pub fn name(&self) -> TypeName {
70 self.to_string().into()
71 }
72
73 #[must_use]
75 pub fn get_struct(&self) -> Option<StructTypes> {
76 match self {
77 Self::Struct(ty) => Some(ty.clone()),
78 _ => None,
79 }
80 }
81}
82
83impl Display for Type {
84 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85 let str = match self {
86 Self::Primitive(primitive) => primitive.to_string(),
87 Self::Struct(struct_type) => struct_type.name.clone(),
88 Self::Array(array_type, size) => {
89 format!("[{:?};{:?}]", array_type.to_string(), size)
90 }
91 };
92 write!(f, "{str}")
93 }
94}
95
96impl TypeAttributes for Type {
97 fn get_attribute_index(&self, attr_name: &ValueName) -> Option<u32> {
98 match self {
99 Self::Struct(st) => st.get_attribute_index(attr_name),
100 _ => None,
101 }
102 }
103 fn get_attribute_type(&self, attr_name: &ValueName) -> Option<Type> {
104 match self {
105 Self::Struct(st) => st.get_attribute_type(attr_name),
106 _ => None,
107 }
108 }
109 fn get_method(&self, method_name: String) -> Option<FunctionName> {
110 match self {
111 Self::Struct(st) => st.get_method(method_name),
112 _ => None,
113 }
114 }
115 fn is_attribute(&self, attr_name: &ValueName) -> bool {
116 match self {
117 Self::Struct(st) => st.is_attribute(attr_name),
118 _ => false,
119 }
120 }
121 fn is_method(&self, method_name: String) -> bool {
122 match self {
123 Self::Struct(st) => st.is_method(method_name),
124 _ => false,
125 }
126 }
127}
128
129impl From<ast::Type<'_>> for Type {
130 fn from(value: ast::Type<'_>) -> Self {
131 match value {
132 ast::Type::Primitive(v) => Self::Primitive(v.into()),
133 ast::Type::Struct(v) => Self::Struct(v.into()),
134 ast::Type::Array(v, s) => Self::Array(Box::new(v.as_ref().clone().into()), s),
135 }
136 }
137}
138
139#[derive(Debug, Clone, PartialEq, Eq)]
142#[cfg_attr(
143 feature = "codec",
144 derive(Serialize, Deserialize),
145 serde(tag = "type", content = "content")
146)]
147pub enum PrimitiveTypes {
148 U8,
149 U16,
150 U32,
151 U64,
152 I8,
153 I16,
154 I32,
155 I64,
156 F32,
157 F64,
158 Bool,
159 Char,
160 Ptr,
161 None,
162}
163
164impl Display for PrimitiveTypes {
165 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
166 let s = match self {
167 Self::U8 => "u8",
168 Self::U16 => "u16",
169 Self::U32 => "u32",
170 Self::U64 => "u64",
171 Self::I8 => "i8",
172 Self::I16 => "i16",
173 Self::I32 => "i32",
174 Self::I64 => "i64",
175 Self::F32 => "f32",
176 Self::F64 => "f64",
177 Self::Bool => "bool",
178 Self::Char => "char",
179 Self::Ptr => "ptr",
180 Self::None => "()",
181 };
182 write!(f, "{s}")
183 }
184}
185
186impl From<ast::PrimitiveTypes> for PrimitiveTypes {
187 fn from(value: ast::PrimitiveTypes) -> Self {
188 match value {
189 ast::PrimitiveTypes::U8 => Self::U8,
190 ast::PrimitiveTypes::U16 => Self::U16,
191 ast::PrimitiveTypes::U32 => Self::U32,
192 ast::PrimitiveTypes::U64 => Self::U64,
193 ast::PrimitiveTypes::I8 => Self::I8,
194 ast::PrimitiveTypes::I16 => Self::I16,
195 ast::PrimitiveTypes::I32 => Self::I32,
196 ast::PrimitiveTypes::I64 => Self::I64,
197 ast::PrimitiveTypes::F32 => Self::F32,
198 ast::PrimitiveTypes::F64 => Self::F64,
199 ast::PrimitiveTypes::Bool => Self::Bool,
200 ast::PrimitiveTypes::Char => Self::Char,
201 ast::PrimitiveTypes::Ptr => Self::Ptr,
202 ast::PrimitiveTypes::None => Self::None,
203 }
204 }
205}
206
207#[derive(Debug, Clone, Eq, PartialEq)]
210#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
211pub struct StructTypes {
212 pub name: String,
214 pub attributes: HashMap<ValueName, StructAttributeType>,
216 pub methods: HashMap<String, FunctionName>,
218}
219
220impl TypeAttributes for StructTypes {
221 fn get_attribute_index(&self, attr_name: &ValueName) -> Option<u32> {
222 self.attributes.get(attr_name).map(|attr| attr.attr_index)
223 }
224 fn get_attribute_type(&self, attr_name: &ValueName) -> Option<Type> {
225 self.attributes
226 .get(attr_name)
227 .map(|attr| attr.attr_type.clone())
228 }
229 fn get_method(&self, method_name: String) -> Option<FunctionName> {
230 self.methods.get(&method_name).cloned()
231 }
232 fn is_attribute(&self, attr_name: &ValueName) -> bool {
233 self.attributes.contains_key(attr_name)
234 }
235 fn is_method(&self, method_name: String) -> bool {
236 self.methods.contains_key(&method_name)
237 }
238}
239
240impl From<ast::StructTypes<'_>> for StructTypes {
241 fn from(value: ast::StructTypes<'_>) -> Self {
242 Self {
243 name: value.name(),
244 attributes: {
245 let mut res = HashMap::new();
246 for (index, val) in value.attributes.iter().enumerate() {
247 let name = (*val.attr_name.fragment()).to_string();
248 let mut v: StructAttributeType = val.clone().into();
249 v.attr_index = u32::try_from(index).unwrap_or_default();
250 res.insert(name.into(), v);
251 }
252 res
253 },
254 methods: HashMap::new(),
255 }
256 }
257}
258
259#[derive(Debug, Clone, Eq, PartialEq)]
261#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
262pub struct StructAttributeType {
263 pub attr_name: ValueName,
265 pub attr_index: u32,
267 pub attr_type: Type,
269}
270
271impl From<ast::StructType<'_>> for StructAttributeType {
272 fn from(value: ast::StructType<'_>) -> Self {
273 Self {
274 attr_name: value.name().into(),
275 attr_type: value.attr_type.into(),
276 attr_index: 0,
277 }
278 }
279}