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