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