Skip to main content

rib/inferred_type/
type_internal.rs

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    // Because function result can be a vector of types
47    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}