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::*, 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 StoreKind: Kind {
74 type Canister: CanisterKind;
75}
76
77pub trait TypeKind:
87 Kind
88 + View
89 + Clone
90 + Default
91 + Serialize
92 + DeserializeOwned
93 + Sanitize
94 + Validate
95 + Visitable
96 + PartialEq
97{
98}
99
100impl<T> TypeKind for T where
101 T: Kind
102 + View
103 + Clone
104 + Default
105 + DeserializeOwned
106 + PartialEq
107 + Serialize
108 + Sanitize
109 + Validate
110 + Visitable
111{
112}
113
114pub trait FieldValues {
123 fn get_value(&self, field: &str) -> Option<Value>;
124}
125
126pub trait FieldValue {
138 fn to_value(&self) -> Value {
139 Value::Unsupported
140 }
141}
142
143impl FieldValue for &str {
144 fn to_value(&self) -> Value {
145 Value::Text((*self).to_string())
146 }
147}
148
149impl FieldValue for String {
150 fn to_value(&self) -> Value {
151 Value::Text(self.clone())
152 }
153}
154
155impl<T> FieldValue for &'_ T
156where
157 T: FieldValue + Copy,
158{
159 fn to_value(&self) -> Value {
160 (*self).to_value()
161 }
162}
163
164impl<T: FieldValue> FieldValue for Option<T> {
165 fn to_value(&self) -> Value {
166 match self {
167 Some(v) => v.to_value(),
168 None => Value::None,
169 }
170 }
171}
172
173impl<T: FieldValue> FieldValue for Vec<T> {
174 fn to_value(&self) -> Value {
175 Value::List(self.iter().map(FieldValue::to_value).collect())
176 }
177}
178
179impl<T: FieldValue> FieldValue for Box<T> {
180 fn to_value(&self) -> Value {
181 (**self).to_value()
182 }
183}
184
185#[macro_export]
187macro_rules! impl_field_value {
188 ( $( $type:ty => $variant:ident ),* $(,)? ) => {
189 $(
190 impl FieldValue for $type {
191 fn to_value(&self) -> Value {
192 Value::$variant((*self).into())
193 }
194 }
195 )*
196 };
197}
198
199impl_field_value!(
200 i8 => Int,
201 i16 => Int,
202 i32 => Int,
203 i64 => Int,
204 u8 => Uint,
205 u16 => Uint,
206 u32 => Uint,
207 u64 => Uint,
208 bool => Bool,
209);
210
211pub trait Inner<T> {
220 fn inner(&self) -> &T;
221 fn into_inner(self) -> T;
222}
223
224#[macro_export]
226macro_rules! impl_inner {
227 ($($type:ty),*) => {
228 $(
229 impl Inner<$type> for $type {
230 fn inner(&self) -> &$type {
231 &self
232 }
233 fn into_inner(self) -> $type {
234 self
235 }
236 }
237 )*
238 };
239}
240
241impl_inner!(
242 bool, f32, f64, i8, i16, i32, i64, i128, String, u8, u16, u32, u64, u128
243);
244
245pub trait Path {
253 const PATH: &'static str;
254}
255
256pub trait Sanitizer<T> {
262 fn sanitize(&self, value: &mut T) -> Result<(), String>;
267}
268
269pub trait Validator<T: ?Sized> {
276 fn validate(&self, value: &T, ctx: &mut dyn VisitorContext);
277}