1use super::*;
19
20pub trait SchemaVisitor {
24 type T;
26
27 fn before_struct_field(&mut self, _field: &NestedFieldRef) -> Result<()> {
29 Ok(())
30 }
31 fn after_struct_field(&mut self, _field: &NestedFieldRef) -> Result<()> {
33 Ok(())
34 }
35 fn before_list_element(&mut self, _field: &NestedFieldRef) -> Result<()> {
37 Ok(())
38 }
39 fn after_list_element(&mut self, _field: &NestedFieldRef) -> Result<()> {
41 Ok(())
42 }
43 fn before_map_key(&mut self, _field: &NestedFieldRef) -> Result<()> {
45 Ok(())
46 }
47 fn after_map_key(&mut self, _field: &NestedFieldRef) -> Result<()> {
49 Ok(())
50 }
51 fn before_map_value(&mut self, _field: &NestedFieldRef) -> Result<()> {
53 Ok(())
54 }
55 fn after_map_value(&mut self, _field: &NestedFieldRef) -> Result<()> {
57 Ok(())
58 }
59
60 fn schema(&mut self, schema: &Schema, value: Self::T) -> Result<Self::T>;
62 fn field(&mut self, field: &NestedFieldRef, value: Self::T) -> Result<Self::T>;
64 fn r#struct(&mut self, r#struct: &StructType, results: Vec<Self::T>) -> Result<Self::T>;
66 fn list(&mut self, list: &ListType, value: Self::T) -> Result<Self::T>;
68 fn map(&mut self, map: &MapType, key_value: Self::T, value: Self::T) -> Result<Self::T>;
70 fn primitive(&mut self, p: &PrimitiveType) -> Result<Self::T>;
72}
73
74pub(crate) fn visit_type<V: SchemaVisitor>(r#type: &Type, visitor: &mut V) -> Result<V::T> {
76 match r#type {
77 Type::Primitive(p) => visitor.primitive(p),
78 Type::List(list) => {
79 visitor.before_list_element(&list.element_field)?;
80 let value = visit_type(&list.element_field.field_type, visitor)?;
81 visitor.after_list_element(&list.element_field)?;
82 visitor.list(list, value)
83 }
84 Type::Map(map) => {
85 let key_result = {
86 visitor.before_map_key(&map.key_field)?;
87 let ret = visit_type(&map.key_field.field_type, visitor)?;
88 visitor.after_map_key(&map.key_field)?;
89 ret
90 };
91
92 let value_result = {
93 visitor.before_map_value(&map.value_field)?;
94 let ret = visit_type(&map.value_field.field_type, visitor)?;
95 visitor.after_map_value(&map.value_field)?;
96 ret
97 };
98
99 visitor.map(map, key_result, value_result)
100 }
101 Type::Struct(s) => visit_struct(s, visitor),
102 }
103}
104
105pub fn visit_struct<V: SchemaVisitor>(s: &StructType, visitor: &mut V) -> Result<V::T> {
107 let mut results = Vec::with_capacity(s.fields().len());
108 for field in s.fields() {
109 visitor.before_struct_field(field)?;
110 let result = visit_type(&field.field_type, visitor)?;
111 visitor.after_struct_field(field)?;
112 let result = visitor.field(field, result)?;
113 results.push(result);
114 }
115
116 visitor.r#struct(s, results)
117}
118
119pub fn visit_schema<V: SchemaVisitor>(schema: &Schema, visitor: &mut V) -> Result<V::T> {
121 let result = visit_struct(&schema.r#struct, visitor)?;
122 visitor.schema(schema, result)
123}
124
125pub trait SchemaWithPartnerVisitor<P> {
129 type T;
131
132 fn before_struct_field(&mut self, _field: &NestedFieldRef, _partner: &P) -> Result<()> {
134 Ok(())
135 }
136 fn after_struct_field(&mut self, _field: &NestedFieldRef, _partner: &P) -> Result<()> {
138 Ok(())
139 }
140 fn before_list_element(&mut self, _field: &NestedFieldRef, _partner: &P) -> Result<()> {
142 Ok(())
143 }
144 fn after_list_element(&mut self, _field: &NestedFieldRef, _partner: &P) -> Result<()> {
146 Ok(())
147 }
148 fn before_map_key(&mut self, _field: &NestedFieldRef, _partner: &P) -> Result<()> {
150 Ok(())
151 }
152 fn after_map_key(&mut self, _field: &NestedFieldRef, _partner: &P) -> Result<()> {
154 Ok(())
155 }
156 fn before_map_value(&mut self, _field: &NestedFieldRef, _partner: &P) -> Result<()> {
158 Ok(())
159 }
160 fn after_map_value(&mut self, _field: &NestedFieldRef, _partner: &P) -> Result<()> {
162 Ok(())
163 }
164
165 fn schema(&mut self, schema: &Schema, partner: &P, value: Self::T) -> Result<Self::T>;
167 fn field(&mut self, field: &NestedFieldRef, partner: &P, value: Self::T) -> Result<Self::T>;
169 fn r#struct(
171 &mut self,
172 r#struct: &StructType,
173 partner: &P,
174 results: Vec<Self::T>,
175 ) -> Result<Self::T>;
176 fn list(&mut self, list: &ListType, partner: &P, value: Self::T) -> Result<Self::T>;
178 fn map(
180 &mut self,
181 map: &MapType,
182 partner: &P,
183 key_value: Self::T,
184 value: Self::T,
185 ) -> Result<Self::T>;
186 fn primitive(&mut self, p: &PrimitiveType, partner: &P) -> Result<Self::T>;
188}
189
190pub trait PartnerAccessor<P> {
192 fn struct_partner<'a>(&self, schema_partner: &'a P) -> Result<&'a P>;
194 fn field_partner<'a>(&self, struct_partner: &'a P, field: &NestedField) -> Result<&'a P>;
196 fn list_element_partner<'a>(&self, list_partner: &'a P) -> Result<&'a P>;
198 fn map_key_partner<'a>(&self, map_partner: &'a P) -> Result<&'a P>;
200 fn map_value_partner<'a>(&self, map_partner: &'a P) -> Result<&'a P>;
202}
203
204pub(crate) fn visit_type_with_partner<P, V: SchemaWithPartnerVisitor<P>, A: PartnerAccessor<P>>(
206 r#type: &Type,
207 partner: &P,
208 visitor: &mut V,
209 accessor: &A,
210) -> Result<V::T> {
211 match r#type {
212 Type::Primitive(p) => visitor.primitive(p, partner),
213 Type::List(list) => {
214 let list_element_partner = accessor.list_element_partner(partner)?;
215 visitor.before_list_element(&list.element_field, list_element_partner)?;
216 let element_results = visit_type_with_partner(
217 &list.element_field.field_type,
218 list_element_partner,
219 visitor,
220 accessor,
221 )?;
222 visitor.after_list_element(&list.element_field, list_element_partner)?;
223 visitor.list(list, partner, element_results)
224 }
225 Type::Map(map) => {
226 let key_partner = accessor.map_key_partner(partner)?;
227 visitor.before_map_key(&map.key_field, key_partner)?;
228 let key_result =
229 visit_type_with_partner(&map.key_field.field_type, key_partner, visitor, accessor)?;
230 visitor.after_map_key(&map.key_field, key_partner)?;
231
232 let value_partner = accessor.map_value_partner(partner)?;
233 visitor.before_map_value(&map.value_field, value_partner)?;
234 let value_result = visit_type_with_partner(
235 &map.value_field.field_type,
236 value_partner,
237 visitor,
238 accessor,
239 )?;
240 visitor.after_map_value(&map.value_field, value_partner)?;
241
242 visitor.map(map, partner, key_result, value_result)
243 }
244 Type::Struct(s) => visit_struct_with_partner(s, partner, visitor, accessor),
245 }
246}
247
248pub fn visit_struct_with_partner<P, V: SchemaWithPartnerVisitor<P>, A: PartnerAccessor<P>>(
250 s: &StructType,
251 partner: &P,
252 visitor: &mut V,
253 accessor: &A,
254) -> Result<V::T> {
255 let mut results = Vec::with_capacity(s.fields().len());
256 for field in s.fields() {
257 let field_partner = accessor.field_partner(partner, field)?;
258 visitor.before_struct_field(field, field_partner)?;
259 let result = visit_type_with_partner(&field.field_type, field_partner, visitor, accessor)?;
260 visitor.after_struct_field(field, field_partner)?;
261 let result = visitor.field(field, field_partner, result)?;
262 results.push(result);
263 }
264
265 visitor.r#struct(s, partner, results)
266}
267
268pub fn visit_schema_with_partner<P, V: SchemaWithPartnerVisitor<P>, A: PartnerAccessor<P>>(
270 schema: &Schema,
271 partner: &P,
272 visitor: &mut V,
273 accessor: &A,
274) -> Result<V::T> {
275 let result = visit_struct_with_partner(
276 &schema.r#struct,
277 accessor.struct_partner(partner)?,
278 visitor,
279 accessor,
280 )?;
281 visitor.schema(schema, partner, result)
282}