swamp_types/
supporting_types.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/swamp
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5
6use crate::cache::TypeCache;
7use crate::{Type, TypeRef};
8use seq_map::SeqMap;
9use source_map_node::Node;
10use std::fmt::{Debug, Display};
11use std::hash::{Hash, Hasher};
12use swamp_symbol::TopLevelSymbolId;
13
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct NamedStructType {
16    pub symbol_id: TopLevelSymbolId,
17    pub name: Node,
18    pub module_path: Vec<String>,
19    pub assigned_name: String,
20    pub anon_struct_type: TypeRef,
21}
22
23impl Hash for NamedStructType {
24    fn hash<H: Hasher>(&self, state: &mut H) {
25        self.module_path.hash(state);
26        state.write(self.assigned_name.as_ref());
27    }
28}
29
30impl NamedStructType {
31    #[must_use]
32    pub fn new(
33        name: Node,
34        assigned_name: &str,
35        symbol_id: TopLevelSymbolId,
36        anon_struct_type: TypeRef,
37        module_path: &[String],
38    ) -> Self {
39        Self {
40            symbol_id,
41            anon_struct_type,
42            name,
43            module_path: module_path.to_vec(),
44            assigned_name: assigned_name.to_string(),
45        }
46    }
47
48    #[must_use]
49    pub fn field_index(&self, field_name: &str) -> Option<usize> {
50        if let crate::TypeKind::AnonymousStruct(anon_struct) = &*self.anon_struct_type.kind {
51            anon_struct
52                .field_name_sorted_fields
53                .get_index(&field_name.to_string())
54        } else {
55            None
56        }
57    }
58
59    #[must_use]
60    pub const fn name(&self) -> &Node {
61        &self.name
62    }
63}
64
65#[derive(Debug, Clone, Eq, PartialEq)]
66pub struct AnonymousStructType {
67    pub field_name_sorted_fields: SeqMap<String, StructTypeField>,
68}
69impl Hash for AnonymousStructType {
70    fn hash<H: Hasher>(&self, state: &mut H) {
71        for (name, field) in &self.field_name_sorted_fields {
72            name.hash(state);
73            field.field_type.id.0.hash(state);
74        }
75    }
76}
77
78impl AnonymousStructType {
79    #[must_use]
80    pub fn new_and_sort_fields(source_ordered_fields: &SeqMap<String, StructTypeField>) -> Self {
81        Self {
82            field_name_sorted_fields: sort_struct_fields2(source_ordered_fields),
83        }
84    }
85
86    #[must_use]
87    pub const fn new(defined_order: SeqMap<String, StructTypeField>) -> Self {
88        Self {
89            field_name_sorted_fields: defined_order,
90        }
91    }
92}
93
94#[derive(Debug, Clone, Eq, PartialEq, Hash)]
95pub struct StructTypeField {
96    pub symbol_id: TopLevelSymbolId,
97    pub identifier: Option<Node>,
98    pub field_type: TypeRef,
99}
100
101impl Display for StructTypeField {
102    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
103        write!(f, "{:?}", self.field_type)
104    }
105}
106
107#[derive(Debug, Eq, PartialEq, Clone, Hash)]
108pub struct Signature {
109    pub parameters: Vec<TypeForParameter>,
110    pub return_type: TypeRef,
111}
112
113impl Signature {
114    #[must_use]
115    pub fn same_type(&self, other: &Self, type_cache: &mut TypeCache) -> bool {
116        if !self
117            .return_type
118            .do_compatible_with(&other.return_type, type_cache)
119        {
120            return false;
121        }
122
123        if self.parameters.len() != other.parameters.len() {
124            return false;
125        }
126
127        for (i, self_param) in self.parameters.iter().enumerate() {
128            let other_param = &other.parameters[i];
129
130            if !self_param
131                .resolved_type
132                .do_compatible_with(&other_param.resolved_type, type_cache)
133            {
134                return false;
135            }
136
137            if self_param.is_mutable != other_param.is_mutable {
138                return false;
139            }
140        }
141
142        true
143    }
144
145    #[must_use]
146    pub fn is_self_mutable(&self) -> bool {
147        self.parameters
148            .first()
149            .is_some_and(|x| x.name == "self" && x.is_mutable)
150    }
151}
152
153#[derive(Debug, Eq, Clone)]
154pub struct TypeForParameter {
155    pub name: String,
156    pub resolved_type: TypeRef,
157    pub is_mutable: bool,
158    pub node: Option<ParameterNode>,
159}
160
161impl PartialEq for TypeForParameter {
162    fn eq(&self, other: &Self) -> bool {
163        self.resolved_type == other.resolved_type && self.is_mutable == other.is_mutable
164    }
165}
166
167impl std::hash::Hash for TypeForParameter {
168    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
169        self.resolved_type.hash(state);
170        self.is_mutable.hash(state);
171    }
172}
173
174impl Display for TypeForParameter {
175    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
176        write!(
177            f,
178            "{}{}: {}",
179            if self.is_mutable { "mut " } else { "" },
180            self.name,
181            self.resolved_type
182        )
183    }
184}
185
186#[derive(Clone, Eq, PartialEq, Hash)]
187pub struct ParameterNode {
188    pub name: Node,
189    pub is_mutable: Option<Node>,
190}
191
192impl Debug for ParameterNode {
193    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
194        write!(f, "Parameter")
195    }
196}
197
198impl ParameterNode {
199    #[inline]
200    #[must_use]
201    pub const fn is_mutable(&self) -> bool {
202        self.is_mutable.is_some()
203    }
204}
205
206#[derive(Debug, Clone, Eq, PartialEq, Hash)]
207pub struct EnumType {
208    pub symbol_id: TopLevelSymbolId,
209    pub name: Node,
210    pub assigned_name: String,
211    pub module_path: Vec<String>,
212    pub variants: SeqMap<String, EnumVariantType>,
213    pub instantiated_type_parameters: Vec<Type>,
214}
215
216impl EnumType {}
217
218impl EnumType {
219    #[must_use]
220    pub fn new(
221        name: Node,
222        assigned_name: &str,
223        symbol_id: TopLevelSymbolId,
224        module_path: Vec<String>,
225    ) -> Self {
226        Self {
227            symbol_id,
228            name,
229            assigned_name: assigned_name.to_string(),
230            module_path,
231            variants: SeqMap::new(),
232            instantiated_type_parameters: Vec::default(),
233        }
234    }
235
236    #[must_use]
237    pub const fn name(&self) -> &Node {
238        &self.name
239    }
240
241    #[must_use]
242    pub fn get_variant(&self, name: &str) -> Option<&EnumVariantType> {
243        self.variants.get(&name.to_string())
244    }
245
246    #[must_use]
247    pub fn are_all_variants_with_blittable_payload(&self) -> bool {
248        self.variants.iter().all(|(_name, variant)| {
249            assert!(
250                variant.payload_type.allowed_for_scoped_borrow(),
251                "what is wrong with this variant {variant}"
252            );
253            variant.payload_type.allowed_for_scoped_borrow()
254        })
255    }
256
257    pub(crate) fn are_all_variants_with_storage_payload(&self) -> bool {
258        self.variants.iter().all(|(_name, variant)| {
259            if !variant.payload_type.is_storage() {
260                eprintln!("this variant can not be stored, please verify why {self}::{variant}");
261            }
262            variant.payload_type.is_storage()
263        })
264    }
265
266    #[must_use]
267    pub fn get_variant_from_index(&self, index: usize) -> Option<&EnumVariantType> {
268        Some(self.variants.values().collect::<Vec<_>>()[index])
269    }
270}
271
272#[derive(Debug, Clone, Eq, PartialEq, Hash)]
273pub struct EnumVariantType {
274    pub common: EnumVariantCommon,
275    pub payload_type: TypeRef, // AnonymousStruct, Unit, or Tuple
276}
277
278impl EnumVariantType {
279    #[must_use]
280    pub const fn common(&self) -> &EnumVariantCommon {
281        &self.common
282    }
283}
284
285#[derive(Clone, Eq, PartialEq, Hash, Debug)]
286pub struct EnumVariantCommon {
287    pub symbol_id: TopLevelSymbolId,
288    pub name: Node,
289    pub assigned_name: String,
290    pub container_index: u8,
291}
292
293impl EnumVariantCommon {
294    #[must_use]
295    pub const fn index(&self) -> u8 {
296        self.container_index
297    }
298}
299
300#[must_use]
301pub fn sort_struct_fields2(
302    unordered_seq_map: &SeqMap<String, StructTypeField>,
303) -> SeqMap<String, StructTypeField> {
304    let mut sorted_pairs: Vec<(&String, &StructTypeField)> = unordered_seq_map.iter().collect();
305    sorted_pairs.sort_by(|a, b| a.0.cmp(b.0));
306
307    sorted_pairs
308        .into_iter()
309        .map(|(name, field)| (name.clone(), field.clone()))
310        .collect()
311}
312
313impl Display for NamedStructType {
314    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
315        write!(f, "{}", self.assigned_name)
316    }
317}
318
319impl Display for AnonymousStructType {
320    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
321        write!(
322            f,
323            "{{ {} }}",
324            seq_fmt::comma(
325                &self
326                    .field_name_sorted_fields
327                    .iter()
328                    .map(|(name, field)| format!("{}: {}", name, field.field_type))
329                    .collect::<Vec<_>>()
330            )
331        )
332    }
333}
334
335impl Display for Signature {
336    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
337        write!(
338            f,
339            "({}) -> {}",
340            seq_fmt::comma(&self.parameters),
341            self.return_type
342        )
343    }
344}
345
346impl Display for EnumType {
347    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
348        if self.instantiated_type_parameters.is_empty() {
349            write!(f, "{}", self.assigned_name)
350        } else {
351            write!(
352                f,
353                "{}<{}>",
354                self.assigned_name,
355                seq_fmt::comma(&self.instantiated_type_parameters)
356            )
357        }
358    }
359}
360
361impl Display for EnumVariantType {
362    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
363        write!(f, "{}", self.payload_type)
364    }
365}