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