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 {
131 fn to_value(&self) -> Value {
132 Value::Unsupported
133 }
134}
135
136impl FieldValue for &str {
137 fn to_value(&self) -> Value {
138 Value::Text((*self).to_string())
139 }
140}
141
142impl FieldValue for String {
143 fn to_value(&self) -> Value {
144 Value::Text(self.clone())
145 }
146}
147
148impl<T: FieldValue + Clone> FieldValue for &T {
149 fn to_value(&self) -> Value {
150 (*self).clone().to_value()
151 }
152}
153
154impl<T: FieldValue> FieldValue for Option<T> {
155 fn to_value(&self) -> Value {
156 match self {
157 Some(v) => v.to_value(),
158 None => Value::None,
159 }
160 }
161}
162
163impl<T: FieldValue> FieldValue for Vec<T> {
164 fn to_value(&self) -> Value {
165 Value::List(self.iter().map(FieldValue::to_value).collect())
166 }
167}
168
169impl<T: FieldValue> FieldValue for Box<T> {
170 fn to_value(&self) -> Value {
171 (**self).to_value()
172 }
173}
174
175#[macro_export]
177macro_rules! impl_field_value {
178 ( $( $type:ty => $variant:ident ),* $(,)? ) => {
179 $(
180 impl FieldValue for $type {
181 fn to_value(&self) -> Value {
182 Value::$variant((*self).into())
183 }
184 }
185 )*
186 };
187}
188
189impl_field_value!(
190 i8 => Int,
191 i16 => Int,
192 i32 => Int,
193 i64 => Int,
194 u8 => Uint,
195 u16 => Uint,
196 u32 => Uint,
197 u64 => Uint,
198 bool => Bool,
199);
200
201pub trait Inner<T> {
210 fn inner(&self) -> &T;
211 fn into_inner(self) -> T;
212}
213
214#[macro_export]
216macro_rules! impl_inner {
217 ($($type:ty),*) => {
218 $(
219 impl Inner<$type> for $type {
220 fn inner(&self) -> &$type {
221 &self
222 }
223 fn into_inner(self) -> $type {
224 self
225 }
226 }
227 )*
228 };
229}
230
231impl_inner!(
232 bool, f32, f64, i8, i16, i32, i64, i128, String, u8, u16, u32, u64, u128
233);
234
235pub trait Path {
243 const PATH: &'static str;
244}
245
246pub trait Sanitizer<T> {
252 fn sanitize(&self, value: &mut T) -> Result<(), String>;
257}
258
259pub trait Validator<T: ?Sized> {
266 fn validate(&self, value: &T, ctx: &mut dyn VisitorContext);
267}