1#[macro_use]
2mod macros;
3mod view;
4mod visitor;
5
6pub use view::*;
7pub use visitor::*;
8
9pub use crate::db::traits::FromKey;
11
12pub use canic_cdk::structures::storable::Storable;
15pub use num_traits::{FromPrimitive as NumFromPrimitive, NumCast, ToPrimitive as NumToPrimitive};
16pub use serde::{Deserialize, Serialize, de::DeserializeOwned};
17pub use std::{
18 cmp::{Eq, Ordering, PartialEq},
19 convert::{AsRef, From, Into},
20 default::Default,
21 fmt::{Debug, Display},
22 hash::Hash,
23 iter::IntoIterator,
24 ops::{Add, AddAssign, Deref, DerefMut, Mul, MulAssign, Sub, SubAssign},
25 str::FromStr,
26};
27
28use crate::{prelude::*, types::Unit, value::ValueEnum, visitor::VisitorContext};
29
30pub trait Kind: Path + 'static {}
40
41impl<T> Kind for T where T: Path + 'static {}
42
43pub trait CanisterKind: Kind {}
48
49pub trait EntityKind: Kind + TypeKind + FieldValues {
54 type PrimaryKey: Copy + Into<Key>;
55 type Store: StoreKind;
56 type Canister: CanisterKind; const ENTITY_NAME: &'static str;
59 const PRIMARY_KEY: &'static str;
60 const FIELDS: &'static [&'static str];
61 const INDEXES: &'static [&'static IndexModel];
62 const MODEL: &'static crate::model::entity::EntityModel;
63
64 fn key(&self) -> Key;
65 fn primary_key(&self) -> Self::PrimaryKey;
66 fn set_primary_key(&mut self, key: Self::PrimaryKey);
67}
68
69pub trait UnitKey: Copy + Into<Key> + unit_key::Sealed {}
75
76impl UnitKey for () {}
77impl UnitKey for Unit {}
78
79pub trait StoreKind: Kind {
84 type Canister: CanisterKind;
85}
86
87mod unit_key {
88 use crate::types::Unit;
89
90 pub trait Sealed {}
92
93 impl Sealed for () {}
94 impl Sealed for Unit {}
95}
96
97pub trait TypeKind:
107 Kind
108 + View
109 + Clone
110 + Default
111 + Serialize
112 + DeserializeOwned
113 + Sanitize
114 + Validate
115 + Visitable
116 + PartialEq
117{
118}
119
120impl<T> TypeKind for T where
121 T: Kind
122 + View
123 + Clone
124 + Default
125 + DeserializeOwned
126 + PartialEq
127 + Serialize
128 + Sanitize
129 + Validate
130 + Visitable
131{
132}
133
134pub trait FieldValues {
143 fn get_value(&self, field: &str) -> Option<Value>;
144}
145
146pub trait FieldValue {
158 fn to_value(&self) -> Value {
159 Value::Unsupported
160 }
161}
162
163pub trait EnumValue {
169 fn to_value_enum(&self) -> ValueEnum;
171}
172
173impl FieldValue for &str {
174 fn to_value(&self) -> Value {
175 Value::Text((*self).to_string())
176 }
177}
178
179impl FieldValue for String {
180 fn to_value(&self) -> Value {
181 Value::Text(self.clone())
182 }
183}
184
185impl<T> FieldValue for &'_ T
186where
187 T: FieldValue + Copy,
188{
189 fn to_value(&self) -> Value {
190 (*self).to_value()
191 }
192}
193
194impl<T: FieldValue> FieldValue for Option<T> {
195 fn to_value(&self) -> Value {
196 match self {
197 Some(v) => v.to_value(),
198 None => Value::None,
199 }
200 }
201}
202
203impl<T: FieldValue> FieldValue for Vec<T> {
204 fn to_value(&self) -> Value {
205 Value::List(self.iter().map(FieldValue::to_value).collect())
206 }
207}
208
209impl<T: FieldValue> FieldValue for Box<T> {
210 fn to_value(&self) -> Value {
211 (**self).to_value()
212 }
213}
214
215#[macro_export]
217macro_rules! impl_field_value {
218 ( $( $type:ty => $variant:ident ),* $(,)? ) => {
219 $(
220 impl FieldValue for $type {
221 fn to_value(&self) -> Value {
222 Value::$variant((*self).into())
223 }
224 }
225 )*
226 };
227}
228
229impl_field_value!(
230 i8 => Int,
231 i16 => Int,
232 i32 => Int,
233 i64 => Int,
234 u8 => Uint,
235 u16 => Uint,
236 u32 => Uint,
237 u64 => Uint,
238 bool => Bool,
239);
240
241pub trait Inner<T> {
250 fn inner(&self) -> &T;
251 fn into_inner(self) -> T;
252}
253
254#[macro_export]
256macro_rules! impl_inner {
257 ($($type:ty),*) => {
258 $(
259 impl Inner<$type> for $type {
260 fn inner(&self) -> &$type {
261 &self
262 }
263 fn into_inner(self) -> $type {
264 self
265 }
266 }
267 )*
268 };
269}
270
271impl_inner!(
272 bool, f32, f64, i8, i16, i32, i64, i128, String, u8, u16, u32, u64, u128
273);
274
275pub trait Path {
283 const PATH: &'static str;
284}
285
286pub trait Sanitizer<T> {
292 fn sanitize(&self, value: &mut T) -> Result<(), String>;
297}
298
299pub trait Validator<T: ?Sized> {
306 fn validate(&self, value: &T, ctx: &mut dyn VisitorContext);
307}