icydb_model/visitor/
traits.rs1use crate::visitor::{
7 PathSegment, VisitorContext, VisitorCore, VisitorMutCore, perform_visit, perform_visit_mut,
8};
9
10pub trait Visitable: Normalize + Validate {
23 fn type_identity(&self) -> &'static str {
26 std::any::type_name::<Self>()
27 }
28
29 fn drive(&self, _: &mut dyn VisitorCore) {}
30 fn drive_mut(&mut self, _: &mut dyn VisitorMutCore) {}
31}
32
33impl<T: Visitable> Visitable for Option<T> {
42 fn drive(&self, visitor: &mut dyn VisitorCore) {
43 if let Some(value) = self.as_ref() {
44 perform_visit(visitor, value, PathSegment::Empty);
45 }
46 }
47
48 fn drive_mut(&mut self, visitor: &mut dyn VisitorMutCore) {
49 if let Some(value) = self.as_mut() {
50 perform_visit_mut(visitor, value, PathSegment::Empty);
51 }
52 }
53}
54
55impl<T: Visitable> Visitable for Vec<T> {
56 fn drive(&self, visitor: &mut dyn VisitorCore) {
57 for (i, value) in self.iter().enumerate() {
58 perform_visit(visitor, value, i);
59 }
60 }
61
62 fn drive_mut(&mut self, visitor: &mut dyn VisitorMutCore) {
63 for (i, value) in self.iter_mut().enumerate() {
64 perform_visit_mut(visitor, value, i);
65 }
66 }
67}
68
69impl<T: Visitable> Visitable for Box<T> {
70 fn type_identity(&self) -> &'static str {
71 (**self).type_identity()
72 }
73
74 fn drive(&self, visitor: &mut dyn VisitorCore) {
75 (**self).drive(visitor);
76 }
77
78 fn drive_mut(&mut self, visitor: &mut dyn VisitorMutCore) {
79 (**self).drive_mut(visitor);
80 }
81}
82
83macro_rules! impl_primitive_visitable {
85 ($($ty:ty),* $(,)?) => {
86 $(impl Visitable for $ty {})*
87 };
88}
89
90impl_primitive_visitable!(
91 i8,
92 i16,
93 i32,
94 i64,
95 i128,
96 u8,
97 u16,
98 u32,
99 u64,
100 u128,
101 f32,
102 f64,
103 bool,
104 String,
105 crate::schema::Account,
106 crate::schema::Blob,
107 crate::schema::Date,
108 crate::schema::Decimal,
109 crate::schema::Duration,
110 crate::schema::Float32,
111 crate::schema::Float64,
112 crate::schema::Principal,
113 crate::schema::Subaccount,
114 crate::schema::Timestamp,
115 crate::schema::U256,
116 crate::schema::Ulid,
117 crate::schema::Unit,
118);
119
120pub trait Normalize: NormalizeAuto + NormalizeCustom {}
128
129impl<T> Normalize for T where T: NormalizeAuto + NormalizeCustom {}
130
131pub trait NormalizeAuto {
143 fn normalize_self(&mut self, _ctx: &mut dyn VisitorContext) {}
144}
145
146impl<T: NormalizeAuto> NormalizeAuto for Option<T> {}
147
148impl<T: NormalizeAuto> NormalizeAuto for Vec<T> {}
149
150impl<T: NormalizeAuto + ?Sized> NormalizeAuto for Box<T> {
151 fn normalize_self(&mut self, ctx: &mut dyn VisitorContext) {
152 (**self).normalize_self(ctx);
153 }
154}
155
156impl_primitive!(NormalizeAuto);
157
158pub trait NormalizeCustom {
166 fn normalize_custom(&mut self, _ctx: &mut dyn VisitorContext) {}
167}
168
169impl<T: NormalizeCustom> NormalizeCustom for Option<T> {}
170
171impl<T: NormalizeCustom> NormalizeCustom for Vec<T> {}
172
173impl<T: NormalizeCustom + ?Sized> NormalizeCustom for Box<T> {
174 fn normalize_custom(&mut self, ctx: &mut dyn VisitorContext) {
175 (**self).normalize_custom(ctx);
176 }
177}
178
179impl_primitive!(NormalizeCustom);
180
181pub trait Validate: ValidateAuto + ValidateCustom {}
189
190impl<T> Validate for T where T: ValidateAuto + ValidateCustom {}
191
192pub trait ValidateAuto {
204 fn validate_self(&self, _ctx: &mut dyn VisitorContext) {}
205}
206
207impl<T: ValidateAuto> ValidateAuto for Option<T> {}
208
209impl<T: ValidateAuto> ValidateAuto for Vec<T> {}
210
211impl<T: ValidateAuto + ?Sized> ValidateAuto for Box<T> {
212 fn validate_self(&self, ctx: &mut dyn VisitorContext) {
213 (**self).validate_self(ctx);
214 }
215}
216
217impl_primitive!(ValidateAuto);
218
219pub trait ValidateCustom {
227 fn validate_custom(&self, _ctx: &mut dyn VisitorContext) {}
228}
229
230impl<T: ValidateCustom> ValidateCustom for Option<T> {}
231
232impl<T: ValidateCustom> ValidateCustom for Vec<T> {}
233
234impl<T: ValidateCustom + ?Sized> ValidateCustom for Box<T> {
235 fn validate_custom(&self, ctx: &mut dyn VisitorContext) {
236 (**self).validate_custom(ctx);
237 }
238}
239
240impl_primitive!(ValidateCustom);
241
242pub trait Normalizer<T> {
244 fn normalize(&self, value: &mut T) -> Result<(), String>;
245
246 fn normalize_with_context(
247 &self,
248 value: &mut T,
249 ctx: &mut dyn VisitorContext,
250 ) -> Result<(), String> {
251 let _ = ctx;
252
253 self.normalize(value)
254 }
255}
256
257pub trait Validator<T: ?Sized> {
259 fn validate(&self, value: &T, ctx: &mut dyn VisitorContext);
260}
261
262#[cfg(test)]
263mod tests;