1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
pub mod xml {
use crate::{Field, Schema};
pub fn cleanup_xml_schema(schema: &mut Schema) {
clean_solitary_nested_values(schema);
turn_duplicates_into_sequence_field(schema);
clean_empty_structs_in_field(schema);
}
pub fn clean_solitary_nested_values(schema: &mut Schema) {
use Schema::*;
match schema {
Null(_) | Boolean(_) | Integer(_) | Float(_) | String(_) | Bytes(_) => {}
Sequence { field, .. } => match &mut field.schema {
Some(schema) => clean_solitary_nested_values(schema),
None => {}
},
Struct { fields, .. } => {
if fields.len() == 1 && fields.contains_key("$value") {
if let Some(Field {
schema: Some(inner_schema),
..
}) = fields.remove("$value")
{
*schema = inner_schema;
}
} else {
for (_, field) in fields.iter_mut() {
match &mut field.schema {
Some(schema) => clean_solitary_nested_values(schema),
None => {}
}
}
}
}
Union { variants } => {
for value in variants {
clean_solitary_nested_values(value);
}
}
}
}
pub fn turn_duplicates_into_sequence_field(schema: &mut Schema) {
clean_field_recursively(schema, _inner_field_cleaning);
fn _inner_field_cleaning(field: &mut Field) {
match &mut field.schema {
Some(schema) => clean_field_recursively(schema, _inner_field_cleaning),
None => {}
}
if field.status.may_be_duplicate {
*field = Field {
status: field.status.clone(),
schema: Some(Schema::Sequence {
field: Box::new(field.clone()),
context: Default::default(),
}),
};
field.status.may_be_duplicate = false;
}
}
}
pub fn clean_empty_structs_in_field(schema: &mut Schema) {
clean_field_recursively(schema, _inner_field_cleaning);
fn _inner_field_cleaning(field: &mut Field) {
match &mut field.schema {
Some(Schema::Struct { fields, .. }) if fields.is_empty() => {
field.schema = None;
}
Some(schema) => clean_field_recursively(schema, _inner_field_cleaning),
None => {}
}
}
}
fn clean_field_recursively(schema: &mut Schema, clean_field: fn(&mut Field)) {
use Schema::*;
match schema {
Null(_) | Boolean(_) | Integer(_) | Float(_) | String(_) | Bytes(_) => {}
Schema::Sequence { field, .. } => clean_field(field),
Schema::Struct { fields, .. } => {
for (_, field) in fields.iter_mut() {
clean_field(field);
}
}
Schema::Union { variants } => {
for value in variants {
clean_field_recursively(value, clean_field);
}
}
}
}
}