1use crate::prelude::*;
2use icydb_schema::ScalarKind;
3use std::str::FromStr;
4
5#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
15pub enum Cardinality {
16 #[default]
17 One,
18 Opt,
19 Many,
20}
21
22impl FromStr for Cardinality {
23 type Err = &'static str;
24
25 fn from_str(s: &str) -> Result<Self, Self::Err> {
26 match s {
27 "One" => Ok(Self::One),
28 "Opt" => Ok(Self::Opt),
29 "Many" => Ok(Self::Many),
30 _ => Err("unknown Cardinality"),
31 }
32 }
33}
34
35#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
44#[remain::sorted]
45pub enum Primitive {
46 Account,
47 Blob,
48 Bool,
49 Date,
50 Decimal,
51 Duration,
52 Float32,
53 Float64,
54 Int8,
55 Int16,
56 Int32,
57 Int64,
58 Int128,
59 IntBig,
60 Nat8,
61 Nat16,
62 Nat32,
63 Nat64,
64 Nat128,
65 NatBig,
66 Principal,
67 Subaccount,
68 Text,
69 Timestamp,
70 Ulid,
71 Unit,
72}
73
74impl FromStr for Primitive {
75 type Err = &'static str;
76
77 fn from_str(s: &str) -> Result<Self, Self::Err> {
78 match s {
79 "Account" => Ok(Self::Account),
80 "Blob" => Ok(Self::Blob),
81 "Bool" => Ok(Self::Bool),
82 "Date" => Ok(Self::Date),
83 "Decimal" => Ok(Self::Decimal),
84 "Duration" => Ok(Self::Duration),
85 "Float32" => Ok(Self::Float32),
86 "Float64" => Ok(Self::Float64),
87 "Int8" => Ok(Self::Int8),
88 "Int16" => Ok(Self::Int16),
89 "Int32" => Ok(Self::Int32),
90 "Int64" => Ok(Self::Int64),
91 "Int128" => Ok(Self::Int128),
92 "IntBig" => Ok(Self::IntBig),
93 "Nat8" => Ok(Self::Nat8),
94 "Nat16" => Ok(Self::Nat16),
95 "Nat32" => Ok(Self::Nat32),
96 "Nat64" => Ok(Self::Nat64),
97 "Nat128" => Ok(Self::Nat128),
98 "NatBig" => Ok(Self::NatBig),
99 "Principal" => Ok(Self::Principal),
100 "Subaccount" => Ok(Self::Subaccount),
101 "Text" => Ok(Self::Text),
102 "Timestamp" => Ok(Self::Timestamp),
103 "Ulid" => Ok(Self::Ulid),
104 "Unit" => Ok(Self::Unit),
105 _ => Err("unknown Primitive"),
106 }
107 }
108}
109
110const fn primitive_scalar_kind(primitive: Primitive) -> ScalarKind {
111 match primitive {
112 Primitive::Account => ScalarKind::Account,
113 Primitive::Blob => ScalarKind::Blob,
114 Primitive::Bool => ScalarKind::Bool,
115 Primitive::Date => ScalarKind::Date,
116 Primitive::Decimal => ScalarKind::Decimal,
117 Primitive::Duration => ScalarKind::Duration,
118 Primitive::Float32 => ScalarKind::Float32,
119 Primitive::Float64 => ScalarKind::Float64,
120 Primitive::Int8 | Primitive::Int16 | Primitive::Int32 | Primitive::Int64 => ScalarKind::Int,
121 Primitive::Int128 => ScalarKind::Int128,
122 Primitive::IntBig => ScalarKind::IntBig,
123 Primitive::Nat8 | Primitive::Nat16 | Primitive::Nat32 | Primitive::Nat64 => ScalarKind::Nat,
124 Primitive::Nat128 => ScalarKind::Nat128,
125 Primitive::NatBig => ScalarKind::NatBig,
126 Primitive::Principal => ScalarKind::Principal,
127 Primitive::Subaccount => ScalarKind::Subaccount,
128 Primitive::Text => ScalarKind::Text,
129 Primitive::Timestamp => ScalarKind::Timestamp,
130 Primitive::Ulid => ScalarKind::Ulid,
131 Primitive::Unit => ScalarKind::Unit,
132 }
133}
134
135impl Primitive {
136 #[must_use]
137 pub const fn supports_arithmetic(self) -> bool {
138 primitive_scalar_kind(self).supports_arithmetic()
139 }
140
141 #[must_use]
142 pub const fn is_primary_key_component_encodable(self) -> bool {
143 primitive_scalar_kind(self).is_primary_key_component_encodable()
144 }
145
146 #[must_use]
147 pub const fn is_primary_key_encodable(self) -> bool {
148 primitive_scalar_kind(self).is_primary_key_component_encodable()
149 }
150
151 #[must_use]
152 pub const fn supports_remainder(self) -> bool {
153 matches!(
154 self,
155 Self::Decimal
156 | Self::Int8
157 | Self::Int16
158 | Self::Int32
159 | Self::Int64
160 | Self::Int128
161 | Self::Nat8
162 | Self::Nat16
163 | Self::Nat32
164 | Self::Nat64
165 | Self::Nat128
166 )
167 }
168
169 #[must_use]
170 pub const fn supports_copy(self) -> bool {
171 !matches!(self, Self::Blob | Self::IntBig | Self::NatBig | Self::Text)
172 }
173
174 #[must_use]
175 pub const fn supports_hash(self) -> bool {
176 !matches!(self, Self::Blob | Self::Unit)
177 }
178
179 #[must_use]
181 pub const fn supports_numeric_value(self) -> bool {
182 matches!(
183 self,
184 Self::Date
185 | Self::Decimal
186 | Self::Duration
187 | Self::Int8
188 | Self::Int16
189 | Self::Int32
190 | Self::Int64
191 | Self::Int128
192 | Self::IntBig
193 | Self::Float32
194 | Self::Float64
195 | Self::Nat8
196 | Self::Nat16
197 | Self::Nat32
198 | Self::Nat64
199 | Self::Nat128
200 | Self::NatBig
201 | Self::Timestamp
202 )
203 }
204
205 #[must_use]
207 pub const fn supports_ord(self) -> bool {
208 primitive_scalar_kind(self).supports_ordering()
209 }
210
211 #[must_use]
216 pub const fn is_decimal(self) -> bool {
217 matches!(self, Self::Decimal)
218 }
219
220 #[must_use]
223 pub const fn is_numeric(self) -> bool {
224 self.is_int() || self.is_float() || self.is_decimal()
225 }
226
227 #[must_use]
228 pub const fn is_float(self) -> bool {
229 matches!(self, Self::Float32 | Self::Float64)
230 }
231
232 #[must_use]
233 pub const fn is_signed_int(self) -> bool {
234 matches!(
235 self,
236 Self::Int8 | Self::Int16 | Self::Int32 | Self::Int64 | Self::Int128 | Self::IntBig
237 )
238 }
239
240 #[must_use]
241 pub const fn is_unsigned_int(self) -> bool {
242 matches!(
243 self,
244 Self::Nat8 | Self::Nat16 | Self::Nat32 | Self::Nat64 | Self::Nat128 | Self::NatBig
245 )
246 }
247
248 #[must_use]
249 pub const fn is_int(self) -> bool {
250 self.is_signed_int() || self.is_unsigned_int()
251 }
252}