1use crate::prelude::*;
2use candid::CandidType;
3use darling::FromMeta;
4use derive_more::{Display, FromStr};
5use proc_macro2::TokenStream;
6use quote::{ToTokens, format_ident, quote};
7
8#[derive(
13 CandidType, Clone, Copy, Default, Debug, Deserialize, Display, Eq, FromStr, PartialEq, Serialize,
14)]
15pub enum Cardinality {
16 #[default]
17 One,
18 Opt,
19 Many,
20}
21
22impl FromMeta for Cardinality {
23 fn from_string(s: &str) -> Result<Self, darling::Error> {
24 s.parse::<Self>()
25 .map_err(|_| darling::Error::unknown_value(s))
26 }
27}
28
29impl ToTokens for Cardinality {
30 fn to_tokens(&self, tokens: &mut TokenStream) {
31 let ident = format_ident!("{self}");
32
33 tokens.extend(quote!(::icydb::schema::types::Cardinality::#ident));
34 }
35}
36
37#[derive(
42 CandidType, Clone, Copy, Debug, Deserialize, Display, Eq, PartialEq, FromStr, Serialize,
43)]
44#[remain::sorted]
45pub enum Primitive {
46 Account,
47 Blob,
48 Bool,
49 Date,
50 Decimal,
51 Duration,
52 E8s,
53 E18s,
54 Float32,
55 Float64,
56 Int,
57 Int8,
58 Int16,
59 Int32,
60 Int64,
61 Int128,
62 Nat,
63 Nat8,
64 Nat16,
65 Nat32,
66 Nat64,
67 Nat128,
68 Principal,
69 Subaccount,
70 Text,
71 Timestamp,
72 Ulid,
73 Unit,
74}
75
76impl Primitive {
77 #[must_use]
78 pub const fn supports_arithmetic(self) -> bool {
79 self.is_int() || self.is_fixed_point() || self.is_decimal()
80 }
81
82 #[must_use]
83 pub const fn supports_copy(self) -> bool {
84 !matches!(self, Self::Blob | Self::Int | Self::Nat | Self::Text)
85 }
86
87 #[must_use]
88 pub const fn supports_display(self) -> bool {
89 !matches!(self, Self::Blob | Self::Unit)
90 }
91
92 #[must_use]
93 pub const fn supports_hash(self) -> bool {
94 !matches!(self, Self::Blob | Self::Unit)
95 }
96
97 #[must_use]
99 pub const fn supports_num_cast(self) -> bool {
100 matches!(
101 self,
102 Self::Date
103 | Self::Decimal
104 | Self::Duration
105 | Self::E8s
106 | Self::E18s
107 | Self::Int8
108 | Self::Int16
109 | Self::Int32
110 | Self::Int64
111 | Self::Float32
112 | Self::Float64
113 | Self::Nat8
114 | Self::Nat16
115 | Self::Nat32
116 | Self::Nat64
117 | Self::Timestamp
118 )
119 }
120
121 #[must_use]
123 pub const fn supports_ord(self) -> bool {
124 !matches!(self, Self::Blob | Self::Unit)
125 }
126
127 #[must_use]
132 pub const fn is_decimal(self) -> bool {
133 matches!(self, Self::Decimal)
134 }
135
136 #[must_use]
139 pub const fn is_numeric(self) -> bool {
140 self.is_int() || self.is_float() || self.is_fixed_point() || self.is_decimal()
141 }
142
143 #[must_use]
144 pub const fn is_float(self) -> bool {
145 matches!(self, Self::Float32 | Self::Float64)
146 }
147
148 #[must_use]
149 pub const fn is_signed_int(self) -> bool {
150 matches!(
151 self,
152 Self::Int | Self::Int8 | Self::Int16 | Self::Int32 | Self::Int64
153 )
154 }
155
156 #[must_use]
157 pub const fn is_unsigned_int(self) -> bool {
158 matches!(
159 self,
160 Self::Nat | Self::Nat8 | Self::Nat16 | Self::Nat32 | Self::Nat64
161 )
162 }
163
164 #[must_use]
165 pub const fn is_int(self) -> bool {
166 self.is_signed_int() || self.is_unsigned_int()
167 }
168
169 #[must_use]
170 pub const fn is_fixed_point(self) -> bool {
171 matches!(self, Self::E8s | Self::E18s)
172 }
173
174 #[must_use]
175 pub fn as_type(self) -> TokenStream {
176 let ident = format_ident!("{self}");
177
178 quote!(::icydb::types::#ident)
179 }
180
181 #[must_use]
182 pub fn num_cast_fn(self) -> String {
183 match self {
184 Self::E18s => "u128",
185 Self::Float32 => "f32",
186 Self::Float64 | Self::Decimal => "f64",
187 Self::Int8 => "i8",
188 Self::Int16 => "i16",
189 Self::Int32 | Self::Date => "i32",
190 Self::Int64 => "i64",
191 Self::Nat8 => "u8",
192 Self::Nat16 => "u16",
193 Self::Nat32 => "u32",
194 Self::Nat64 | Self::Duration | Self::E8s | Self::Timestamp => "u64",
195 _ => panic!("unexpected primitive type"),
196 }
197 .into()
198 }
199}
200
201impl FromMeta for Primitive {
202 fn from_string(s: &str) -> Result<Self, darling::Error> {
203 s.parse::<Self>()
204 .map_err(|_| darling::Error::unknown_value(s))
205 }
206}
207
208impl ToTokens for Primitive {
209 fn to_tokens(&self, tokens: &mut TokenStream) {
210 let ident = format_ident!("{self}");
211
212 tokens.extend(quote!(::icydb::schema::types::Primitive::#ident));
213 }
214}
215
216#[derive(CandidType, Clone, Copy, Debug, Deserialize, Display, FromStr, Serialize)]
221pub enum StoreType {
222 Data,
223 Index,
224}
225
226impl FromMeta for StoreType {
227 fn from_string(s: &str) -> Result<Self, darling::Error> {
228 s.parse::<Self>()
229 .map_err(|_| darling::Error::unknown_value(s))
230 }
231}
232
233impl ToTokens for StoreType {
234 fn to_tokens(&self, tokens: &mut TokenStream) {
235 let ident = format_ident!("{self}");
236
237 tokens.extend(quote!(::icydb::schema::types::StoreType::#ident));
238 }
239}