1use crate::inferred_type::TypeOrigin;
16use crate::{ComponentDependencyKey, InferredType, InstanceType};
17use std::hash::{Hash, Hasher};
18
19#[derive(Debug, Clone, Ord, PartialOrd)]
20pub enum TypeInternal {
21 Bool,
22 S8,
23 U8,
24 S16,
25 U16,
26 S32,
27 U32,
28 S64,
29 U64,
30 F32,
31 F64,
32 Chr,
33 Str,
34 List(InferredType),
35 Tuple(Vec<InferredType>),
36 Record(Vec<(String, InferredType)>),
37 Flags(Vec<String>),
38 Enum(Vec<String>),
39 Option(InferredType),
40 Result {
41 ok: Option<InferredType>,
42 error: Option<InferredType>,
43 },
44 Variant(Vec<(String, Option<InferredType>)>),
45 Resource {
46 name: Option<String>,
47 owner: Option<String>,
48 resource_id: u64,
49 resource_mode: u8,
50 },
51 Range {
52 from: InferredType,
53 to: Option<InferredType>,
54 },
55 Instance {
56 instance_type: Box<InstanceType>,
57 },
58 AllOf(Vec<InferredType>),
59 Unknown,
60 Sequence(Vec<InferredType>),
62}
63
64impl TypeInternal {
65 pub fn is_instance(&self) -> bool {
66 matches!(self, TypeInternal::Instance { .. })
67 }
68
69 pub fn to_inferred_type(&self) -> InferredType {
70 InferredType::new(self.clone(), TypeOrigin::NoOrigin)
71 }
72
73 pub fn narrow_to_single_component(
74 &mut self,
75 component_dependency_key: &ComponentDependencyKey,
76 ) {
77 if let TypeInternal::Instance { instance_type } = self {
78 instance_type.narrow_to_single_component(component_dependency_key)
79 }
80 }
81}
82
83impl Eq for TypeInternal {}
84
85impl Hash for TypeInternal {
86 fn hash<H: Hasher>(&self, state: &mut H) {
87 match self {
88 TypeInternal::Bool => 0.hash(state),
89 TypeInternal::S8 => 1.hash(state),
90 TypeInternal::U8 => 2.hash(state),
91 TypeInternal::S16 => 3.hash(state),
92 TypeInternal::U16 => 4.hash(state),
93 TypeInternal::S32 => 5.hash(state),
94 TypeInternal::U32 => 6.hash(state),
95 TypeInternal::S64 => 7.hash(state),
96 TypeInternal::U64 => 8.hash(state),
97 TypeInternal::F32 => 9.hash(state),
98 TypeInternal::F64 => 10.hash(state),
99 TypeInternal::Chr => 11.hash(state),
100 TypeInternal::Str => 12.hash(state),
101 TypeInternal::List(inner) => {
102 13.hash(state);
103 inner.hash(state);
104 }
105 TypeInternal::Tuple(inner) => {
106 14.hash(state);
107 inner.hash(state);
108 }
109 TypeInternal::Record(fields) => {
110 15.hash(state);
111 let mut sorted_fields = fields.clone();
112 sorted_fields.sort_by(|a, b| a.0.cmp(&b.0));
113 sorted_fields.hash(state);
114 }
115 TypeInternal::Flags(flags) => {
116 16.hash(state);
117 let mut sorted_flags = flags.clone();
118 sorted_flags.sort();
119 sorted_flags.hash(state);
120 }
121 TypeInternal::Enum(variants) => {
122 17.hash(state);
123 let mut sorted_variants = variants.clone();
124 sorted_variants.sort();
125 sorted_variants.hash(state);
126 }
127 TypeInternal::Option(inner) => {
128 18.hash(state);
129 inner.hash(state);
130 }
131 TypeInternal::Result { ok, error } => {
132 19.hash(state);
133 ok.hash(state);
134 error.hash(state);
135 }
136 TypeInternal::Variant(fields) => {
137 20.hash(state);
138 let mut sorted_fields = fields.clone();
139 sorted_fields.sort_by(|a, b| a.0.cmp(&b.0));
140 sorted_fields.hash(state);
141 }
142 TypeInternal::Resource {
143 resource_id,
144 resource_mode,
145 name,
146 owner,
147 } => {
148 21.hash(state);
149 resource_id.hash(state);
150 resource_mode.hash(state);
151 if let Some(name) = name {
152 name.hash(state);
153 } else {
154 "name-unknown".hash(state);
155 }
156
157 if let Some(owner) = owner {
158 owner.hash(state);
159 } else {
160 "owner-unknown".hash(state);
161 }
162 }
163 TypeInternal::Range { from, to } => {
164 22.hash(state);
165 from.hash(state);
166 to.hash(state);
167 }
168 TypeInternal::Instance { instance_type } => {
169 23.hash(state);
170 instance_type.hash(state);
171 }
172 TypeInternal::AllOf(types) | TypeInternal::Sequence(types) => {
173 24.hash(state);
174 let mut sorted_types = types.clone();
175 sorted_types.sort();
176 sorted_types.hash(state);
177 }
178 TypeInternal::Unknown => 25.hash(state),
179 }
180 }
181}
182
183impl PartialEq for TypeInternal {
184 fn eq(&self, other: &Self) -> bool {
185 match (self, other) {
186 (TypeInternal::Bool, TypeInternal::Bool) => true,
187 (TypeInternal::S8, TypeInternal::S8) => true,
188 (TypeInternal::U8, TypeInternal::U8) => true,
189 (TypeInternal::S16, TypeInternal::S16) => true,
190 (TypeInternal::U16, TypeInternal::U16) => true,
191 (TypeInternal::S32, TypeInternal::S32) => true,
192 (TypeInternal::U32, TypeInternal::U32) => true,
193 (TypeInternal::S64, TypeInternal::S64) => true,
194 (TypeInternal::U64, TypeInternal::U64) => true,
195 (TypeInternal::F32, TypeInternal::F32) => true,
196 (TypeInternal::F64, TypeInternal::F64) => true,
197 (TypeInternal::Chr, TypeInternal::Chr) => true,
198 (TypeInternal::Str, TypeInternal::Str) => true,
199 (TypeInternal::List(t1), TypeInternal::List(t2)) => t1 == t2,
200 (TypeInternal::Tuple(ts1), TypeInternal::Tuple(ts2)) => ts1 == ts2,
201 (TypeInternal::Record(fs1), TypeInternal::Record(fs2)) => fs1 == fs2,
202 (TypeInternal::Flags(vs1), TypeInternal::Flags(vs2)) => vs1 == vs2,
203 (TypeInternal::Enum(vs1), TypeInternal::Enum(vs2)) => vs1 == vs2,
204 (TypeInternal::Option(t1), TypeInternal::Option(t2)) => t1 == t2,
205 (
206 TypeInternal::Result {
207 ok: ok1,
208 error: error1,
209 },
210 TypeInternal::Result {
211 ok: ok2,
212 error: error2,
213 },
214 ) => ok1 == ok2 && error1 == error2,
215 (TypeInternal::Variant(vs1), TypeInternal::Variant(vs2)) => vs1 == vs2,
216 (
217 TypeInternal::Resource {
218 resource_id: id1,
219 resource_mode: mode1,
220 name: name1,
221 owner: owner1,
222 },
223 TypeInternal::Resource {
224 resource_id: id2,
225 resource_mode: mode2,
226 name: name2,
227 owner: owner2,
228 },
229 ) => id1 == id2 && mode1 == mode2 && name1 == name2 && owner1 == owner2,
230 (
231 TypeInternal::Range {
232 from: from1,
233 to: to1,
234 },
235 TypeInternal::Range {
236 from: from2,
237 to: to2,
238 },
239 ) => from1 == from2 && to1 == to2,
240 (
241 TypeInternal::Instance { instance_type: t1 },
242 TypeInternal::Instance { instance_type: t2 },
243 ) => t1 == t2,
244 (TypeInternal::Unknown, TypeInternal::Unknown) => true,
245
246 (TypeInternal::AllOf(ts1), TypeInternal::AllOf(ts2)) => {
247 let mut ts1_sorted = ts1.clone();
248 let mut ts2_sorted = ts2.clone();
249 ts1_sorted.sort();
250 ts2_sorted.sort();
251 ts1_sorted == ts2_sorted
252 }
253 (TypeInternal::Sequence(ts1), TypeInternal::Sequence(ts2)) => {
254 let mut ts1_sorted = ts1.clone();
255 let mut ts2_sorted = ts2.clone();
256 ts1_sorted.sort();
257 ts2_sorted.sort();
258 ts1_sorted == ts2_sorted
259 }
260
261 _ => false,
262 }
263 }
264}