1use std::cell::RefCell;
2use std::collections::HashMap;
3use std::rc::{Rc, Weak};
4
5use crate::common::FilePosition;
6use crate::idl;
7
8use super::errors::ValidationError;
9use super::fieldset::Fieldset;
10use super::fqtn::FQTN;
11use super::namespace::Namespace;
12use super::options::Range;
13use super::r#enum::Enum;
14use super::r#struct::Struct;
15use super::typemap::TypeMap;
16
17#[derive(Clone)]
18pub enum Type {
19 None,
21 Boolean,
22 Integer,
23 Float,
24 String,
25 UUID,
26 Date,
27 Time,
28 DateTime,
29 Option(Box<Type>),
31 Result(Box<Type>, Box<Type>),
32 Array(Box<Array>),
33 Map(Box<Map>),
34 Ref(TypeRef),
36 Builtin(String),
38}
39
40#[derive(Clone)]
41pub enum TypeRef {
42 Enum(EnumRef),
43 Struct(StructRef),
44 Fieldset(FieldsetRef),
45 Unresolved { fqtn: FQTN, generics: Vec<Type> },
46}
47
48#[derive(Clone)]
49pub struct EnumRef {
50 pub enum_: Weak<RefCell<Enum>>,
51 pub generics: Vec<Type>,
52}
53#[derive(Clone)]
54
55pub struct StructRef {
56 pub struct_: Weak<RefCell<Struct>>,
57 pub generics: Vec<Type>,
58}
59
60#[derive(Clone)]
61pub struct FieldsetRef {
62 pub fieldset: Weak<RefCell<Fieldset>>,
63 pub generics: Vec<Type>,
64}
65
66#[derive(Clone)]
67pub struct Array {
68 pub length: Range,
69 pub item_type: Type,
70}
71
72#[derive(Clone)]
73pub struct Map {
74 pub length: Range,
75 pub key_type: Type,
76 pub value_type: Type,
77}
78
79#[derive(Clone)]
80pub enum UserDefinedType {
81 Enum(Rc<RefCell<Enum>>),
82 Struct(Rc<RefCell<Struct>>),
83 Fieldset(Rc<RefCell<Fieldset>>),
84}
85
86impl Type {
87 pub(crate) fn from_idl_ref(
88 ityperef: &idl::TypeRef,
89 ns: &Namespace,
90 builtin_types: &HashMap<String, String>,
91 ) -> Self {
92 match ityperef.name.as_str() {
94 "None" => Self::None,
95 "Boolean" => Self::Boolean,
96 "Integer" => Self::Integer,
97 "Float" => Self::Float,
98 "String" => Self::String,
99 "UUID" => Self::UUID,
100 "Date" => Self::Date,
101 "Time" => Self::Time,
102 "DateTime" => Self::DateTime,
103 "Option" => Self::Option(Box::new(Type::from_idl(
104 &ityperef.generics[0],
105 ns,
106 &builtin_types,
107 ))),
108 "Result" => Self::Result(
109 Box::new(Type::from_idl(&ityperef.generics[0], ns, &builtin_types)),
110 Box::new(Type::from_idl(&ityperef.generics[1], ns, &builtin_types)),
111 ),
112 name => match builtin_types.get(name) {
113 Some(value) => Self::Builtin(value.to_owned()),
114 None => Self::Ref(TypeRef::from_idl(ityperef, ns, &builtin_types)),
115 },
116 }
117 }
118 pub(crate) fn from_idl(
119 itype: &idl::Type,
120 ns: &Namespace,
121 builtin_types: &HashMap<String, String>,
122 ) -> Self {
123 match itype {
124 idl::Type::Ref(ityperef) => Self::from_idl_ref(&ityperef, &ns, &builtin_types),
125 idl::Type::Array(item_type) => Self::Array(Box::new(Array {
126 item_type: Self::from_idl(item_type, ns, &builtin_types),
127 length: Range {
128 start: None,
129 end: None,
130 }, })),
132 idl::Type::Map(key_type, value_type) => Self::Map(Box::new(Map {
133 key_type: Self::from_idl(key_type, ns, &builtin_types),
134 value_type: Self::from_idl(value_type, ns, &builtin_types),
135 length: Range {
136 start: None,
137 end: None,
138 }, })),
140 }
141 }
142 pub(crate) fn resolve(&mut self, type_map: &TypeMap) -> Result<(), ValidationError> {
143 match self {
144 Self::None
145 | Self::Boolean
146 | Self::Integer
147 | Self::Float
148 | Self::String
149 | Self::UUID
150 | Self::Date
151 | Self::Time
152 | Self::DateTime => Ok(()),
153 Self::Option(some) => some.resolve(type_map),
155 Self::Result(ok, err) => {
156 ok.resolve(type_map)?;
157 err.resolve(type_map)?;
158 Ok(())
159 }
160 Self::Array(array) => array.resolve(type_map),
161 Self::Map(map) => map.resolve(type_map),
162 Self::Ref(typeref) => typeref.resolve(type_map),
164 Self::Builtin(_) => Ok(()),
166 }
167 }
168 pub(crate) fn is_scalar(&self) -> bool {
170 match self {
171 Self::None
172 | Self::Boolean
173 | Self::Integer
174 | Self::Float
175 | Self::String
176 | Self::UUID
177 | Self::Date
178 | Self::Time
179 | Self::DateTime => true,
180 Self::Option(type_) => type_.is_scalar(),
181 Self::Result(_, _) => false,
182 Self::Array(_) => false,
183 Self::Map(_) => false,
184 Self::Ref(_) => false,
185 Self::Builtin(_) => true,
186 }
187 }
188}
189
190impl TypeRef {
191 pub(crate) fn from_idl(
192 ityperef: &idl::TypeRef,
193 ns: &Namespace,
194 builtin_types: &HashMap<String, String>,
195 ) -> Self {
196 Self::Unresolved {
197 fqtn: FQTN::from_idl(ityperef, ns),
198 generics: ityperef
199 .generics
200 .iter()
201 .map(|itype| Type::from_idl(itype, ns, &builtin_types))
202 .collect(),
203 }
204 }
205 pub(crate) fn resolve(&mut self, type_map: &TypeMap) -> Result<(), ValidationError> {
206 if let Self::Unresolved { fqtn, generics } = self {
207 let ud_type = type_map.get(fqtn);
208 let position = FilePosition { line: 0, column: 0 }; *self = match ud_type {
210 Some(ud_type) => {
211 if generics.len() != ud_type.generics().len() {
212 return Err(ValidationError::GenericsMissmatch {
213 fqtn: fqtn.clone(),
214 position,
215 });
216 }
217 match ud_type {
218 UserDefinedType::Enum(enum_) => TypeRef::Enum(EnumRef {
219 enum_: Rc::downgrade(&enum_),
220 generics: generics.clone(),
221 }),
222 UserDefinedType::Struct(struct_) => TypeRef::Struct(StructRef {
223 struct_: Rc::downgrade(&struct_),
224 generics: generics.clone(),
225 }),
226 UserDefinedType::Fieldset(fieldset) => TypeRef::Fieldset(FieldsetRef {
227 fieldset: Rc::downgrade(&fieldset),
228 generics: generics.clone(),
229 }),
230 }
231 }
232 None => {
233 return Err(ValidationError::NoSuchType {
234 fqtn: fqtn.clone(),
235 position,
236 })
237 }
238 }
239 }
240 Ok(())
241 }
242 pub fn fqtn(&self) -> FQTN {
243 match self {
244 TypeRef::Enum(enum_) => enum_.enum_.upgrade().unwrap().borrow().fqtn.clone(),
245 TypeRef::Struct(struct_) => struct_.struct_.upgrade().unwrap().borrow().fqtn.clone(),
246 TypeRef::Fieldset(fieldset) => {
247 fieldset.fieldset.upgrade().unwrap().borrow().fqtn.clone()
248 }
249 TypeRef::Unresolved { fqtn, generics: _ } => fqtn.clone(),
250 }
251 }
252 pub fn generics(&self) -> &Vec<Type> {
253 match self {
254 TypeRef::Enum(enum_) => &enum_.generics,
255 TypeRef::Struct(struct_) => &struct_.generics,
256 TypeRef::Fieldset(fieldset) => &fieldset.generics,
257 TypeRef::Unresolved { fqtn: _, generics } => generics,
258 }
259 }
260}
261
262impl Array {
263 pub(crate) fn resolve(&mut self, type_map: &TypeMap) -> Result<(), ValidationError> {
264 self.item_type.resolve(type_map)
265 }
266}
267
268impl Map {
269 pub(crate) fn resolve(&mut self, type_map: &TypeMap) -> Result<(), ValidationError> {
270 self.key_type.resolve(type_map)?;
271 self.value_type.resolve(type_map)?;
272 Ok(())
273 }
274}
275
276impl UserDefinedType {
277 pub fn fqtn(&self) -> FQTN {
278 match self {
279 Self::Enum(t) => t.borrow().fqtn.clone(),
280 Self::Fieldset(t) => t.borrow().fqtn.clone(),
281 Self::Struct(t) => t.borrow().fqtn.clone(),
282 }
283 }
284 pub(crate) fn resolve(&mut self, type_map: &TypeMap) -> Result<(), ValidationError> {
285 match self {
286 Self::Enum(t) => t.borrow_mut().resolve(type_map),
287 Self::Fieldset(t) => t.borrow_mut().resolve(type_map),
288 Self::Struct(t) => t.borrow_mut().resolve(type_map),
289 }
290 }
291 pub(crate) fn generics(&self) -> Vec<String> {
292 match self {
293 Self::Enum(t) => t.borrow().generics.clone(),
294 Self::Fieldset(t) => t.borrow().generics.clone(),
295 Self::Struct(t) => t.borrow().generics.clone(),
296 }
297 }
298}