1#[macro_use]
2mod macros;
3mod view;
4mod visitor;
5
6pub use view::*;
7pub use visitor::*;
8
9pub use crate::db::traits::{FilterView, Filterable};
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
63 fn key(&self) -> Key;
64 fn primary_key(&self) -> Self::PrimaryKey;
65 fn set_primary_key(&mut self, key: Self::PrimaryKey);
66}
67
68pub trait StoreKind: Kind {
73 type Canister: CanisterKind;
74}
75
76pub trait TypeKind:
86 Kind
87 + View
88 + Clone
89 + Default
90 + Serialize
91 + DeserializeOwned
92 + Sanitize
93 + Validate
94 + Visitable
95 + PartialEq
96{
97}
98
99impl<T> TypeKind for T where
100 T: Kind
101 + View
102 + Clone
103 + Default
104 + DeserializeOwned
105 + PartialEq
106 + Serialize
107 + Sanitize
108 + Validate
109 + Visitable
110{
111}
112
113pub trait FieldValues {
122 fn get_value(&self, field: &str) -> Option<Value>;
123}
124
125pub trait FieldValue {
130 fn to_value(&self) -> Value {
131 Value::Unsupported
132 }
133}
134
135impl FieldValue for &str {
136 fn to_value(&self) -> Value {
137 Value::Text((*self).to_string())
138 }
139}
140
141impl FieldValue for String {
142 fn to_value(&self) -> Value {
143 Value::Text(self.clone())
144 }
145}
146
147impl<T: FieldValue + Clone> FieldValue for &T {
148 fn to_value(&self) -> Value {
149 (*self).clone().to_value()
150 }
151}
152
153impl<T: FieldValue> FieldValue for Option<T> {
154 fn to_value(&self) -> Value {
155 match self {
156 Some(v) => v.to_value(),
157 None => Value::None,
158 }
159 }
160}
161
162impl<T: FieldValue> FieldValue for Vec<T> {
163 fn to_value(&self) -> Value {
164 Value::List(self.iter().map(FieldValue::to_value).collect())
165 }
166}
167
168impl<T: FieldValue> FieldValue for Box<T> {
169 fn to_value(&self) -> Value {
170 (**self).to_value()
171 }
172}
173
174#[macro_export]
176macro_rules! impl_field_value {
177 ( $( $type:ty => $variant:ident ),* $(,)? ) => {
178 $(
179 impl FieldValue for $type {
180 fn to_value(&self) -> Value {
181 Value::$variant((*self).into())
182 }
183 }
184 )*
185 };
186}
187
188impl_field_value!(
189 i8 => Int,
190 i16 => Int,
191 i32 => Int,
192 i64 => Int,
193 u8 => Uint,
194 u16 => Uint,
195 u32 => Uint,
196 u64 => Uint,
197 bool => Bool,
198);
199
200pub trait Inner<T> {
209 fn inner(&self) -> &T;
210 fn into_inner(self) -> T;
211}
212
213#[macro_export]
215macro_rules! impl_inner {
216 ($($type:ty),*) => {
217 $(
218 impl Inner<$type> for $type {
219 fn inner(&self) -> &$type {
220 &self
221 }
222 fn into_inner(self) -> $type {
223 self
224 }
225 }
226 )*
227 };
228}
229
230impl_inner!(
231 bool, f32, f64, i8, i16, i32, i64, i128, String, u8, u16, u32, u64, u128
232);
233
234pub trait Path {
242 const PATH: &'static str;
243}
244
245pub trait Sanitizer<T> {
251 fn sanitize(&self, value: &mut T) -> Result<(), String>;
256}
257
258pub trait Validator<T: ?Sized> {
265 fn validate(&self, value: &T, ctx: &mut dyn VisitorContext);
266}