icydb_core/traits/
view.rs1use candid::CandidType;
2use std::{
3 collections::{BTreeMap, BTreeSet, HashMap, HashSet},
4 hash::{BuildHasher, Hash},
5};
6
7pub trait AsView: Sized {
15 type ViewType: Default;
16
17 fn as_view(&self) -> Self::ViewType;
18 fn from_view(view: Self::ViewType) -> Self;
19}
20
21impl AsView for () {
22 type ViewType = Self;
23
24 fn as_view(&self) -> Self::ViewType {}
25 fn from_view((): Self::ViewType) -> Self {}
26}
27
28impl AsView for String {
29 type ViewType = Self;
30
31 fn as_view(&self) -> Self::ViewType {
32 self.clone()
33 }
34
35 fn from_view(view: Self::ViewType) -> Self {
36 view
37 }
38}
39
40impl<T: AsView> AsView for Box<T> {
42 type ViewType = T::ViewType;
43
44 fn as_view(&self) -> Self::ViewType {
45 T::as_view(self.as_ref())
47 }
48
49 fn from_view(view: Self::ViewType) -> Self {
50 Self::new(T::from_view(view))
52 }
53}
54
55impl<T: AsView> AsView for Option<T> {
56 type ViewType = Option<T::ViewType>;
57
58 fn as_view(&self) -> Self::ViewType {
59 self.as_ref().map(AsView::as_view)
60 }
61
62 fn from_view(view: Self::ViewType) -> Self {
63 view.map(T::from_view)
64 }
65}
66
67impl<T: AsView> AsView for Vec<T> {
68 type ViewType = Vec<T::ViewType>;
69
70 fn as_view(&self) -> Self::ViewType {
71 self.iter().map(AsView::as_view).collect()
72 }
73
74 fn from_view(view: Self::ViewType) -> Self {
75 view.into_iter().map(T::from_view).collect()
76 }
77}
78
79impl<T, S> AsView for HashSet<T, S>
80where
81 T: AsView + Eq + Hash + Clone,
82 S: BuildHasher + Default,
83{
84 type ViewType = Vec<T::ViewType>;
85
86 fn as_view(&self) -> Self::ViewType {
87 self.iter().map(AsView::as_view).collect()
88 }
89
90 fn from_view(view: Self::ViewType) -> Self {
91 view.into_iter().map(T::from_view).collect()
92 }
93}
94
95impl<K, V, S> AsView for HashMap<K, V, S>
96where
97 K: AsView + Eq + Hash + Clone,
98 V: AsView,
99 S: BuildHasher + Default,
100{
101 type ViewType = Vec<(K::ViewType, V::ViewType)>;
102
103 fn as_view(&self) -> Self::ViewType {
104 self.iter()
105 .map(|(k, v)| (k.as_view(), v.as_view()))
106 .collect()
107 }
108
109 fn from_view(view: Self::ViewType) -> Self {
110 view.into_iter()
111 .map(|(k, v)| (K::from_view(k), V::from_view(v)))
112 .collect()
113 }
114}
115
116impl<T> AsView for BTreeSet<T>
117where
118 T: AsView + Ord + Clone,
119{
120 type ViewType = Vec<T::ViewType>;
121
122 fn as_view(&self) -> Self::ViewType {
123 self.iter().map(AsView::as_view).collect()
124 }
125
126 fn from_view(view: Self::ViewType) -> Self {
127 view.into_iter().map(T::from_view).collect()
128 }
129}
130
131impl<K, V> AsView for BTreeMap<K, V>
132where
133 K: AsView + Ord + Clone,
134 V: AsView,
135{
136 type ViewType = Vec<(K::ViewType, V::ViewType)>;
137
138 fn as_view(&self) -> Self::ViewType {
139 self.iter()
140 .map(|(k, v)| (k.as_view(), v.as_view()))
141 .collect()
142 }
143
144 fn from_view(view: Self::ViewType) -> Self {
145 view.into_iter()
146 .map(|(k, v)| (K::from_view(k), V::from_view(v)))
147 .collect()
148 }
149}
150
151#[macro_export]
152macro_rules! impl_view {
153 ($($type:ty),*) => {
154 $(
155 impl AsView for $type {
156 type ViewType = Self;
157
158 fn as_view(&self) -> Self::ViewType {
159 *self
160 }
161
162 fn from_view(view: Self::ViewType) -> Self {
163 view
164 }
165 }
166 )*
167 };
168}
169
170impl_view!(bool, i8, i16, i32, i64, u8, u16, u32, u64);
171
172impl AsView for f32 {
173 type ViewType = Self;
174
175 fn as_view(&self) -> Self::ViewType {
176 *self
177 }
178
179 fn from_view(view: Self::ViewType) -> Self {
180 if view.is_finite() {
181 if view == 0.0 { 0.0 } else { view }
182 } else {
183 0.0
184 }
185 }
186}
187
188impl AsView for f64 {
189 type ViewType = Self;
190
191 fn as_view(&self) -> Self::ViewType {
192 *self
193 }
194
195 fn from_view(view: Self::ViewType) -> Self {
196 if view.is_finite() {
197 if view == 0.0 { 0.0 } else { view }
198 } else {
199 0.0
200 }
201 }
202}
203
204pub trait CreateView: AsView {
209 type CreateViewType: CandidType + Default;
214
215 fn from_create_view(view: Self::CreateViewType) -> Self;
216}
217
218pub trait UpdateView: AsView {
223 type UpdateViewType: CandidType + Default;
225}