ralik/context/types/
mod.rs1use crate::error::{
2 InvalidArrayType, InvalidBoolType, InvalidCharType, InvalidIntegerType, InvalidStringType, InvalidTupleType,
3};
4use crate::{Type, TypeHandle};
5
6use super::Context;
7
8mod type_container;
9pub(super) use type_container::TypeContainer;
10
11impl Context {
12 pub fn get_type(&self, key: impl AsRef<str>) -> Option<TypeHandle> {
13 self
14 .0
15 .types
16 .data
17 .read()
18 .unwrap()
19 .get(key.as_ref())
20 .map(TypeHandle::from)
21 }
22
23 pub fn get_unit_type(&self) -> Result<TypeHandle, InvalidTupleType> {
24 let name = "()";
25 if let Some(tuple_type) = self.get_type(name) {
26 return Ok(tuple_type);
27 }
28
29 let mut types = self.0.types.data.write().unwrap();
32
33 if let Some(tuple_type) = types.get(name) {
36 return Ok(tuple_type.into());
37 }
38
39 let tuple_type = TypeHandle::new(crate::types::TupleType::new_unit("()"));
40 assert!(types.insert(tuple_type.clone().into()) == true);
41
42 Ok(tuple_type)
43 }
44
45 pub fn get_bool_type(&self) -> Result<TypeHandle, InvalidBoolType> {
46 self
47 .get_type(crate::types::bool_name())
48 .ok_or_else(|| InvalidBoolType::Missing)
49 }
50
51 pub fn get_char_type(&self) -> Result<TypeHandle, InvalidCharType> {
52 self
53 .get_type(crate::types::char_name())
54 .ok_or_else(|| InvalidCharType::Missing)
55 }
56
57 pub fn get_integer_type(&self) -> Result<TypeHandle, InvalidIntegerType> {
58 self
59 .get_type(crate::types::integer_name())
60 .ok_or_else(|| InvalidIntegerType::Missing)
61 }
62
63 pub fn get_string_type(&self) -> Result<TypeHandle, InvalidStringType> {
64 self
65 .get_type(crate::types::string_name())
66 .ok_or_else(|| InvalidStringType::Missing)
67 }
68
69 pub fn get_tuple_type(
70 &self,
71 element_type_names: impl Iterator<Item = impl AsRef<str> + std::fmt::Debug> + Clone,
72 ) -> Result<TypeHandle, InvalidTupleType> {
73 let name = crate::types::make_tuple_name(element_type_names.clone());
74 if let Some(tuple_type) = self.get_type(&name) {
75 return Ok(tuple_type);
76 }
77
78 let mut types = self.0.types.data.write().unwrap();
81
82 if let Some(tuple_type) = types.get(name.as_str()) {
85 return Ok(tuple_type.into());
86 }
87
88 let element_types: Result<Vec<TypeHandle>, _> = element_type_names
89 .map(|name| types.get(name.as_ref()).map(TypeHandle::from).ok_or(name))
90 .collect();
91 if let Err(element_type_name) = element_types {
92 return Err(InvalidTupleType::MissingSubtype {
93 make_tuple_name: name,
94 missing_element_type_name: element_type_name.as_ref().into(),
95 });
96 }
97 let element_types = element_types.unwrap();
98
99 let tuple_type = TypeHandle::new(crate::types::TupleType::new(name, element_types));
100 assert!(types.insert(tuple_type.clone().into()) == true);
101
102 Ok(tuple_type)
103 }
104
105 pub fn get_array_type(&self, element_type_name: &str) -> Result<TypeHandle, InvalidArrayType> {
106 let name = crate::types::array_name(element_type_name);
107 if let Some(array_type) = self.get_type(&name) {
108 return Ok(array_type);
109 }
110
111 let mut types = self.0.types.data.write().unwrap();
114
115 if let Some(array_type) = types.get(name.as_str()) {
118 return Ok(array_type.into());
119 }
120
121 let element_type =
122 types
123 .get(element_type_name)
124 .map(TypeHandle::from)
125 .ok_or_else(|| InvalidArrayType::MissingSubtype {
126 element_type_name: element_type_name.into(),
127 })?;
128
129 let array_type = TypeHandle::new(crate::types::ArrayType::new(name, element_type));
130 assert!(types.insert(array_type.clone().into()) == true);
131
132 Ok(array_type)
133 }
134
135 pub fn get_option_type(&self, element_type_name: &str) -> Result<TypeHandle, InvalidArrayType> {
136 let name = crate::types::make_option_name(element_type_name);
137 if let Some(option_type) = self.get_type(&name) {
138 return Ok(option_type);
139 }
140
141 let mut types = self.0.types.data.write().unwrap();
144
145 if let Some(option_type) = types.get(name.as_str()) {
148 return Ok(option_type.into());
149 }
150
151 let element_type =
152 types
153 .get(element_type_name)
154 .map(TypeHandle::from)
155 .ok_or_else(|| InvalidArrayType::MissingSubtype {
156 element_type_name: element_type_name.into(),
157 })?;
158
159 let option_type = TypeHandle::new(crate::types::OptionType::new(name, element_type));
160 assert!(types.insert(option_type.clone().into()) == true);
161
162 Ok(option_type)
163 }
164
165 pub fn insert_type(&self, value: impl Type + 'static) -> TypeHandle {
166 let handle = TypeHandle::new(value);
167
168 {
170 let types = self.0.types.data.read().unwrap();
171 let type_parameters = handle.type_parameters().iter();
172 let field_types = handle.fields().1.iter();
173 let variant_types = handle
174 .variants()
175 .into_iter()
176 .flat_map(|(_variant_names, variants)| variants)
177 .flat_map(|variant| {
178 use crate::types::Variant;
179 match variant {
180 Variant::Unit(_id) => None,
181 Variant::Tuple(_id, types) => Some(types.iter()),
182 Variant::Struct(_id, _names, types) => Some(types.iter()),
183 }
184 })
185 .flatten();
186
187 for type_parameter in type_parameters.chain(field_types).chain(variant_types) {
188 let registered = types.get(type_parameter.name());
189 assert!(registered.is_some(), "All dependent types must be registered first");
190 assert!(
191 TypeHandle::is_same(type_parameter, registered.unwrap().into()),
192 "All dependent types must refer to the exact same object that is registered under that name"
193 );
194 }
195 }
196
197 let mut types = self.0.types.data.write().unwrap();
198 assert!(types.insert(handle.clone().into()) == true);
199 handle
200 }
201}