1use super::*;
19use crate::spec::VariantType;
20
21pub trait SchemaVisitor {
25 type T;
27
28 fn before_struct_field(&mut self, _field: &NestedFieldRef) -> Result<()> {
30 Ok(())
31 }
32 fn after_struct_field(&mut self, _field: &NestedFieldRef) -> Result<()> {
34 Ok(())
35 }
36 fn before_list_element(&mut self, _field: &NestedFieldRef) -> Result<()> {
38 Ok(())
39 }
40 fn after_list_element(&mut self, _field: &NestedFieldRef) -> Result<()> {
42 Ok(())
43 }
44 fn before_map_key(&mut self, _field: &NestedFieldRef) -> Result<()> {
46 Ok(())
47 }
48 fn after_map_key(&mut self, _field: &NestedFieldRef) -> Result<()> {
50 Ok(())
51 }
52 fn before_map_value(&mut self, _field: &NestedFieldRef) -> Result<()> {
54 Ok(())
55 }
56 fn after_map_value(&mut self, _field: &NestedFieldRef) -> Result<()> {
58 Ok(())
59 }
60
61 fn schema(&mut self, schema: &Schema, value: Self::T) -> Result<Self::T>;
63 fn field(&mut self, field: &NestedFieldRef, value: Self::T) -> Result<Self::T>;
65 fn r#struct(&mut self, r#struct: &StructType, results: Vec<Self::T>) -> Result<Self::T>;
67 fn list(&mut self, list: &ListType, value: Self::T) -> Result<Self::T>;
69 fn map(&mut self, map: &MapType, key_value: Self::T, value: Self::T) -> Result<Self::T>;
71 fn primitive(&mut self, p: &PrimitiveType) -> Result<Self::T>;
73
74 fn variant(&mut self, v: &VariantType) -> Result<Self::T>;
76}
77
78pub(crate) fn visit_type<V: SchemaVisitor>(r#type: &Type, visitor: &mut V) -> Result<V::T> {
80 match r#type {
81 Type::Primitive(p) => visitor.primitive(p),
82 Type::List(list) => {
83 visitor.before_list_element(&list.element_field)?;
84 let value = visit_type(&list.element_field.field_type, visitor)?;
85 visitor.after_list_element(&list.element_field)?;
86 visitor.list(list, value)
87 }
88 Type::Map(map) => {
89 let key_result = {
90 visitor.before_map_key(&map.key_field)?;
91 let ret = visit_type(&map.key_field.field_type, visitor)?;
92 visitor.after_map_key(&map.key_field)?;
93 ret
94 };
95
96 let value_result = {
97 visitor.before_map_value(&map.value_field)?;
98 let ret = visit_type(&map.value_field.field_type, visitor)?;
99 visitor.after_map_value(&map.value_field)?;
100 ret
101 };
102
103 visitor.map(map, key_result, value_result)
104 }
105 Type::Struct(s) => visit_struct(s, visitor),
106 Type::Variant(v) => visitor.variant(v),
107 }
108}
109
110pub fn visit_struct<V: SchemaVisitor>(s: &StructType, visitor: &mut V) -> Result<V::T> {
112 let mut results = Vec::with_capacity(s.fields().len());
113 for field in s.fields() {
114 visitor.before_struct_field(field)?;
115 let result = visit_type(&field.field_type, visitor)?;
116 visitor.after_struct_field(field)?;
117 let result = visitor.field(field, result)?;
118 results.push(result);
119 }
120
121 visitor.r#struct(s, results)
122}
123
124pub fn visit_schema<V: SchemaVisitor>(schema: &Schema, visitor: &mut V) -> Result<V::T> {
126 let result = visit_struct(&schema.r#struct, visitor)?;
127 visitor.schema(schema, result)
128}
129
130pub trait SchemaWithPartnerVisitor<P> {
134 type T;
136
137 fn before_struct_field(&mut self, _field: &NestedFieldRef, _partner: &P) -> Result<()> {
139 Ok(())
140 }
141 fn after_struct_field(&mut self, _field: &NestedFieldRef, _partner: &P) -> Result<()> {
143 Ok(())
144 }
145 fn before_list_element(&mut self, _field: &NestedFieldRef, _partner: &P) -> Result<()> {
147 Ok(())
148 }
149 fn after_list_element(&mut self, _field: &NestedFieldRef, _partner: &P) -> Result<()> {
151 Ok(())
152 }
153 fn before_map_key(&mut self, _field: &NestedFieldRef, _partner: &P) -> Result<()> {
155 Ok(())
156 }
157 fn after_map_key(&mut self, _field: &NestedFieldRef, _partner: &P) -> Result<()> {
159 Ok(())
160 }
161 fn before_map_value(&mut self, _field: &NestedFieldRef, _partner: &P) -> Result<()> {
163 Ok(())
164 }
165 fn after_map_value(&mut self, _field: &NestedFieldRef, _partner: &P) -> Result<()> {
167 Ok(())
168 }
169
170 fn schema(&mut self, schema: &Schema, partner: &P, value: Self::T) -> Result<Self::T>;
172 fn field(&mut self, field: &NestedFieldRef, partner: &P, value: Self::T) -> Result<Self::T>;
174 fn r#struct(
176 &mut self,
177 r#struct: &StructType,
178 partner: &P,
179 results: Vec<Self::T>,
180 ) -> Result<Self::T>;
181 fn list(&mut self, list: &ListType, partner: &P, value: Self::T) -> Result<Self::T>;
183 fn map(
185 &mut self,
186 map: &MapType,
187 partner: &P,
188 key_value: Self::T,
189 value: Self::T,
190 ) -> Result<Self::T>;
191 fn primitive(&mut self, p: &PrimitiveType, partner: &P) -> Result<Self::T>;
193 fn variant(&mut self, v: &VariantType, partner: &P) -> Result<Self::T>;
195}
196
197pub trait PartnerAccessor<P> {
199 fn struct_partner<'a>(&self, schema_partner: &'a P) -> Result<&'a P>;
201 fn field_partner<'a>(&self, struct_partner: &'a P, field: &NestedField) -> Result<&'a P>;
203 fn list_element_partner<'a>(&self, list_partner: &'a P) -> Result<&'a P>;
205 fn map_key_partner<'a>(&self, map_partner: &'a P) -> Result<&'a P>;
207 fn map_value_partner<'a>(&self, map_partner: &'a P) -> Result<&'a P>;
209}
210
211pub(crate) fn visit_type_with_partner<P, V: SchemaWithPartnerVisitor<P>, A: PartnerAccessor<P>>(
213 r#type: &Type,
214 partner: &P,
215 visitor: &mut V,
216 accessor: &A,
217) -> Result<V::T> {
218 match r#type {
219 Type::Primitive(p) => visitor.primitive(p, partner),
220 Type::List(list) => {
221 let list_element_partner = accessor.list_element_partner(partner)?;
222 visitor.before_list_element(&list.element_field, list_element_partner)?;
223 let element_results = visit_type_with_partner(
224 &list.element_field.field_type,
225 list_element_partner,
226 visitor,
227 accessor,
228 )?;
229 visitor.after_list_element(&list.element_field, list_element_partner)?;
230 visitor.list(list, partner, element_results)
231 }
232 Type::Map(map) => {
233 let key_partner = accessor.map_key_partner(partner)?;
234 visitor.before_map_key(&map.key_field, key_partner)?;
235 let key_result =
236 visit_type_with_partner(&map.key_field.field_type, key_partner, visitor, accessor)?;
237 visitor.after_map_key(&map.key_field, key_partner)?;
238
239 let value_partner = accessor.map_value_partner(partner)?;
240 visitor.before_map_value(&map.value_field, value_partner)?;
241 let value_result = visit_type_with_partner(
242 &map.value_field.field_type,
243 value_partner,
244 visitor,
245 accessor,
246 )?;
247 visitor.after_map_value(&map.value_field, value_partner)?;
248
249 visitor.map(map, partner, key_result, value_result)
250 }
251 Type::Struct(s) => visit_struct_with_partner(s, partner, visitor, accessor),
252 Type::Variant(v) => visitor.variant(v, partner),
253 }
254}
255
256pub fn visit_struct_with_partner<P, V: SchemaWithPartnerVisitor<P>, A: PartnerAccessor<P>>(
258 s: &StructType,
259 partner: &P,
260 visitor: &mut V,
261 accessor: &A,
262) -> Result<V::T> {
263 let mut results = Vec::with_capacity(s.fields().len());
264 for field in s.fields() {
265 let field_partner = accessor.field_partner(partner, field)?;
266 visitor.before_struct_field(field, field_partner)?;
267 let result = visit_type_with_partner(&field.field_type, field_partner, visitor, accessor)?;
268 visitor.after_struct_field(field, field_partner)?;
269 let result = visitor.field(field, field_partner, result)?;
270 results.push(result);
271 }
272
273 visitor.r#struct(s, partner, results)
274}
275
276pub fn visit_schema_with_partner<P, V: SchemaWithPartnerVisitor<P>, A: PartnerAccessor<P>>(
278 schema: &Schema,
279 partner: &P,
280 visitor: &mut V,
281 accessor: &A,
282) -> Result<V::T> {
283 let result = visit_struct_with_partner(
284 &schema.r#struct,
285 accessor.struct_partner(partner)?,
286 visitor,
287 accessor,
288 )?;
289 visitor.schema(schema, partner, result)
290}