icydb_core/traits/
visitable.rs1use crate::{
2 traits::{Sanitize, Validate},
3 visitor::{PathSegment, Visitor, VisitorMut, perform_visit, perform_visit_mut},
4};
5use std::{
6 collections::{HashMap, HashSet},
7 hash::BuildHasher,
8};
9
10pub trait Visitable: Sanitize + Validate {
15 fn drive(&self, _: &mut dyn Visitor) {}
16 fn drive_mut(&mut self, _: &mut dyn VisitorMut) {}
17}
18
19impl<T: Visitable> Visitable for Option<T> {
20 fn drive(&self, visitor: &mut dyn Visitor) {
21 if let Some(value) = self {
22 perform_visit(visitor, value, PathSegment::Empty);
23 }
24 }
25
26 fn drive_mut(&mut self, visitor: &mut dyn VisitorMut) {
27 if let Some(value) = self {
28 perform_visit_mut(visitor, value, PathSegment::Empty);
29 }
30 }
31}
32
33impl<T: Visitable> Visitable for Vec<T> {
34 fn drive(&self, visitor: &mut dyn Visitor) {
35 for (i, value) in self.iter().enumerate() {
36 perform_visit(visitor, value, i);
37 }
38 }
39
40 fn drive_mut(&mut self, visitor: &mut dyn VisitorMut) {
41 for (i, value) in self.iter_mut().enumerate() {
42 perform_visit_mut(visitor, value, i);
43 }
44 }
45}
46
47impl<T: Visitable> Visitable for Box<T> {
48 fn drive(&self, visitor: &mut dyn Visitor) {
49 (**self).drive(visitor);
52 }
53
54 fn drive_mut(&mut self, visitor: &mut dyn VisitorMut) {
55 (**self).drive_mut(visitor);
57 }
58}
59
60impl<T, S> Visitable for HashSet<T, S>
61where
62 T: Visitable + Eq + std::hash::Hash,
63 S: BuildHasher + Default,
64{
65 fn drive(&self, visitor: &mut dyn Visitor) {
66 for item in self {
69 perform_visit(visitor, item, PathSegment::Empty);
70 }
71 }
72
73 fn drive_mut(&mut self, visitor: &mut dyn VisitorMut) {
74 let mut new_set = Self::with_hasher(S::default());
77
78 for mut item in self.drain() {
79 perform_visit_mut(visitor, &mut item, PathSegment::Empty);
80 new_set.insert(item);
81 }
82
83 *self = new_set;
84 }
85}
86
87impl<K, V, S> Visitable for HashMap<K, V, S>
88where
89 K: Visitable + Eq + std::hash::Hash,
90 V: Visitable,
91 S: BuildHasher + Default,
92{
93 fn drive(&self, visitor: &mut dyn Visitor) {
94 for (k, v) in self {
96 perform_visit(visitor, k, "key");
97 perform_visit(visitor, v, "value");
98 }
99 }
100
101 fn drive_mut(&mut self, visitor: &mut dyn VisitorMut) {
102 let mut new_map = Self::with_hasher(S::default());
105
106 for (mut k, mut v) in self.drain() {
107 perform_visit_mut(visitor, &mut k, "key");
108 perform_visit_mut(visitor, &mut v, "value");
109 new_map.insert(k, v);
110 }
111
112 *self = new_map;
113 }
114}
115
116impl_primitive!(Visitable);