1use super::{
4 BinEntry,
5 data::*,
6 binvalue_map_type,
7 binvalue_map_keytype,
8};
9
10#[allow(missing_docs)]
18pub trait BinVisitor {
19 type Error;
20
21 fn traverse_entry(&mut self, value: &BinEntry) -> Result<(), Self::Error> {
25 value.traverse_bin(self)
26 }
27
28 fn visit_type(&mut self, _btype: BinType) -> bool { true }
30
31 fn visit_entry(&mut self, _value: &BinEntry) -> Result<bool, Self::Error> { Ok(true) }
32 fn visit_field(&mut self, value: &BinField) -> Result<bool, Self::Error> { Ok(self.visit_type(value.vtype)) }
33
34 fn visit_none(&mut self, _value: &BinNone) -> Result<(), Self::Error> { Ok(()) }
35 fn visit_bool(&mut self, _value: &BinBool) -> Result<(), Self::Error> { Ok(()) }
36 fn visit_s8(&mut self, _value: &BinS8) -> Result<(), Self::Error> { Ok(()) }
37 fn visit_u8(&mut self, _value: &BinU8) -> Result<(), Self::Error> { Ok(()) }
38 fn visit_s16(&mut self, _value: &BinS16) -> Result<(), Self::Error> { Ok(()) }
39 fn visit_u16(&mut self, _value: &BinU16) -> Result<(), Self::Error> { Ok(()) }
40 fn visit_s32(&mut self, _value: &BinS32) -> Result<(), Self::Error> { Ok(()) }
41 fn visit_u32(&mut self, _value: &BinU32) -> Result<(), Self::Error> { Ok(()) }
42 fn visit_s64(&mut self, _value: &BinS64) -> Result<(), Self::Error> { Ok(()) }
43 fn visit_u64(&mut self, _value: &BinU64) -> Result<(), Self::Error> { Ok(()) }
44 fn visit_float(&mut self, _value: &BinFloat) -> Result<(), Self::Error> { Ok(()) }
45 fn visit_vec2(&mut self, _value: &BinVec2) -> Result<(), Self::Error> { Ok(()) }
46 fn visit_vec3(&mut self, _value: &BinVec3) -> Result<(), Self::Error> { Ok(()) }
47 fn visit_vec4(&mut self, _value: &BinVec4) -> Result<(), Self::Error> { Ok(()) }
48 fn visit_matrix(&mut self, _value: &BinMatrix) -> Result<(), Self::Error> { Ok(()) }
49 fn visit_color(&mut self, _value: &BinColor) -> Result<(), Self::Error> { Ok(()) }
50 fn visit_string(&mut self, _value: &BinString) -> Result<(), Self::Error> { Ok(()) }
51 fn visit_hash(&mut self, _value: &BinHash) -> Result<(), Self::Error> { Ok(()) }
52 fn visit_path(&mut self, _value: &BinPath) -> Result<(), Self::Error> { Ok(()) }
53 fn visit_list(&mut self, value: &BinList) -> Result<bool, Self::Error> {
54 Ok(self.visit_type(BinType::List) && self.visit_type(value.vtype))
55 }
56 fn visit_struct(&mut self, _value: &BinStruct) -> Result<bool, Self::Error> {
57 Ok(self.visit_type(BinType::Struct))
58 }
59 fn visit_embed(&mut self, _value: &BinEmbed) -> Result<bool, Self::Error> {
60 Ok(self.visit_type(BinType::Embed))
61 }
62 fn visit_link(&mut self, _value: &BinLink) -> Result<(), Self::Error> { Ok(()) }
63 fn visit_option(&mut self, value: &BinOption) -> Result<bool, Self::Error> {
64 Ok(self.visit_type(BinType::Option) && self.visit_type(value.vtype))
65 }
66 fn visit_map(&mut self, _value: &BinMap) -> Result<bool, Self::Error> {
67 Ok(self.visit_type(BinType::Map))
68 }
69 fn visit_flag(&mut self, _value: &BinFlag) -> Result<(), Self::Error> { Ok(()) }
70}
71
72pub trait BinTraversal<BV: BinVisitor + ?Sized> {
74 fn traverse_bin(&self, visitor: &mut BV) -> Result<(), BV::Error>;
76}
77
78macro_rules! impl_traversal {
79 ($t:ty, $visit:ident) => {
80 impl<BV: BinVisitor + ?Sized> BinTraversal<BV> for $t {
81 #[inline]
82 fn traverse_bin(&self, visitor: &mut BV) -> Result<(), BV::Error> {
83 visitor.$visit(self)
84 }
85 }
86 }
87}
88
89impl_traversal!(BinNone, visit_none);
90impl_traversal!(BinBool, visit_bool);
91impl_traversal!(BinS8, visit_s8);
92impl_traversal!(BinU8, visit_u8);
93impl_traversal!(BinS16, visit_s16);
94impl_traversal!(BinU16, visit_u16);
95impl_traversal!(BinS32, visit_s32);
96impl_traversal!(BinU32, visit_u32);
97impl_traversal!(BinS64, visit_s64);
98impl_traversal!(BinU64, visit_u64);
99impl_traversal!(BinFloat, visit_float);
100impl_traversal!(BinVec2, visit_vec2);
101impl_traversal!(BinVec3, visit_vec3);
102impl_traversal!(BinVec4, visit_vec4);
103impl_traversal!(BinMatrix, visit_matrix);
104impl_traversal!(BinColor, visit_color);
105impl_traversal!(BinString, visit_string);
106impl_traversal!(BinHash, visit_hash);
107impl_traversal!(BinPath, visit_path);
108impl_traversal!(BinLink, visit_link);
109impl_traversal!(BinFlag, visit_flag);
110
111
112impl<BV: BinVisitor + ?Sized> BinTraversal<BV> for BinEntry {
113 fn traverse_bin(&self, visitor: &mut BV) -> Result<(), BV::Error> {
114 if visitor.visit_entry(self)? {
115 for field in self.fields.iter() {
116 field.traverse_bin(visitor)?;
117 }
118 }
119 Ok(())
120 }
121}
122
123impl<BV: BinVisitor + ?Sized> BinTraversal<BV> for BinField {
124 fn traverse_bin(&self, visitor: &mut BV) -> Result<(), BV::Error> {
125 if visitor.visit_field(self)? {
126 binvalue_map_type!(self.vtype, T, {
127 self.downcast::<T>().unwrap().traverse_bin(visitor)?;
128 });
129 }
130 Ok(())
131 }
132}
133
134impl<BV: BinVisitor + ?Sized> BinTraversal<BV> for BinStruct {
135 fn traverse_bin(&self, visitor: &mut BV) -> Result<(), BV::Error> {
136 if visitor.visit_struct(self)? {
137 for field in self.fields.iter() {
138 field.traverse_bin(visitor)?;
139 }
140 }
141 Ok(())
142 }
143}
144
145impl<BV: BinVisitor + ?Sized> BinTraversal<BV> for BinEmbed {
146 fn traverse_bin(&self, visitor: &mut BV) -> Result<(), BV::Error> {
147 if visitor.visit_embed(self)? {
148 for field in self.fields.iter() {
149 field.traverse_bin(visitor)?;
150 }
151 }
152 Ok(())
153 }
154}
155
156impl<BV: BinVisitor + ?Sized> BinTraversal<BV> for BinOption {
157 fn traverse_bin(&self, visitor: &mut BV) -> Result<(), BV::Error> {
158 if visitor.visit_option(self)? {
159 if self.value.is_some() {
160 binvalue_map_type!(self.vtype, V, {
161 self.downcast::<V>().unwrap().traverse_bin(visitor)?;
162 });
163 }
164 }
165 Ok(())
166 }
167}
168
169impl<BV: BinVisitor + ?Sized> BinTraversal<BV> for BinList {
170 fn traverse_bin(&self, visitor: &mut BV) -> Result<(), BV::Error> {
171 if visitor.visit_list(self)? {
172 binvalue_map_type!(self.vtype, V, {
173 for v in self.downcast::<V>().unwrap().iter() {
174 v.traverse_bin(visitor)?;
175 }
176 });
177 }
178 Ok(())
179 }
180}
181
182impl<BV: BinVisitor + ?Sized> BinTraversal<BV> for BinMap {
183 fn traverse_bin(&self, visitor: &mut BV) -> Result<(), BV::Error> {
184 if visitor.visit_map(self)? {
185 binvalue_map_keytype!(self.ktype, K, {
186 binvalue_map_type!(self.vtype, V, {
187 for (k, v) in self.downcast::<K, V>().unwrap() {
188 k.traverse_bin(visitor)?;
189 v.traverse_bin(visitor)?;
190 }
191 })
192 });
193 }
194 Ok(())
195 }
196}
197