rib/inferred_type/
type_internal.rs

1// Copyright 2024-2025 Golem Cloud
2//
3// Licensed under the Golem Source License v1.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://license.golem.cloud/LICENSE
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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    // Because function result can be a vector of types
59    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}