swamp_types/
lib.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
6mod cache;
7mod calc_compat;
8mod flag_helper;
9mod flags;
10pub mod prelude;
11mod pretty_print;
12mod supporting_types;
13mod type_kind;
14
15use crate::flags::TypeFlags;
16pub use crate::type_kind::TypeKind;
17use std::fmt::{Display, Formatter};
18use std::rc::Rc;
19
20#[derive(PartialEq, Clone, Eq, Hash, Copy, Debug)]
21pub struct TypeId(u32);
22
23impl TypeId {
24    pub const EMPTY: u32 = 0xffffffff;
25
26    #[must_use]
27    pub const fn new(id: u32) -> Self {
28        Self(id)
29    }
30
31    #[must_use]
32    pub const fn inner(&self) -> u32 {
33        self.0
34    }
35}
36
37impl Display for TypeId {
38    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
39        write!(f, "{}", self.0)
40    }
41}
42
43#[derive(Debug, Clone, PartialEq, Eq, Hash)]
44pub struct Type {
45    pub id: TypeId,
46    pub flags: TypeFlags,
47    pub kind: Rc<TypeKind>,
48}
49
50pub type TypeRef = Rc<Type>;
51
52impl Display for Type {
53    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
54        write!(f, "{}|{}", self.id, self.kind)
55    }
56}
57
58impl Type {
59    #[inline]
60    #[must_use]
61    pub const fn is_scalar(&self) -> bool {
62        self.flags.contains(TypeFlags::IS_SCALAR)
63    }
64
65    #[inline]
66    #[must_use]
67    pub const fn can_be_stored_in_field(&self) -> bool {
68        self.flags.contains(TypeFlags::IS_STORAGE)
69    }
70
71    #[inline]
72    #[must_use]
73    pub const fn can_be_stored_in_variable(&self) -> bool {
74        self.flags.contains(TypeFlags::IS_BLITTABLE)
75    }
76
77    #[inline]
78    #[must_use]
79    pub const fn is_storage(&self) -> bool {
80        self.flags.contains(TypeFlags::IS_STORAGE)
81    }
82
83    #[inline]
84    #[must_use]
85    pub const fn allowed_as_return_type(&self) -> bool {
86        self.flags.contains(TypeFlags::IS_ALLOWED_RETURN)
87    }
88
89    #[inline]
90    #[must_use]
91    pub const fn allowed_as_parameter_type(&self) -> bool {
92        self.flags.contains(TypeFlags::IS_ALLOWED_RETURN)
93    }
94
95    #[inline]
96    #[must_use]
97    pub const fn is_blittable(&self) -> bool {
98        self.flags.contains(TypeFlags::IS_BLITTABLE)
99    }
100
101    /// Check if this type requires explicit collection storage allocation from caller
102    /// This includes all aggregate types including optionals that need memory
103    /// allocation and proper setup of the r0 register by the caller
104    #[must_use]
105    pub fn collection_view_that_needs_explicit_storage(&self) -> bool {
106        match &*self.kind {
107            // Dynamic collections that need explicit storage
108            TypeKind::DynamicLengthVecView(_)
109            | TypeKind::DynamicLengthMapView(_, _)
110            | TypeKind::StackView(_)
111            | TypeKind::QueueView(_)
112            | TypeKind::SparseView(_)
113            | TypeKind::GridView(_)
114            | TypeKind::SliceView(_) => true,
115
116            // Optional types that contain types needing storage
117            TypeKind::Optional(inner_type) => {
118                inner_type.collection_view_that_needs_explicit_storage()
119            }
120
121            _ => false,
122        }
123    }
124}