@@ -47,6 +47,8 @@ pub enum JsonFlattenError {
47
47
NonObjectInArray ,
48
48
}
49
49
50
+ // Recursively flattens JSON objects and arrays, e.g. with the separator `.`, starting from the TOP
51
+ // `{"key": "value", "nested_key": {"key":"value"}}` becomes `{"key": "value", "nested_key.key": "value"}`
50
52
pub fn flatten (
51
53
nested_value : & mut Value ,
52
54
separator : & str ,
@@ -67,6 +69,7 @@ pub fn flatten(
67
69
}
68
70
Value :: Array ( arr) => {
69
71
for nested_value in arr {
72
+ // Recursively flatten each element, ONLY in the TOP array
70
73
flatten (
71
74
nested_value,
72
75
separator,
@@ -83,6 +86,19 @@ pub fn flatten(
83
86
Ok ( ( ) )
84
87
}
85
88
89
+ // Checks if a JSON value is null or empty
90
+ fn is_null_or_empty ( value : & Value ) -> bool {
91
+ match value {
92
+ Value :: Null => true ,
93
+ Value :: Object ( o) if o. is_empty ( ) => true ,
94
+ Value :: Array ( a) if a. is_empty ( ) => true ,
95
+ Value :: String ( s) if s. is_empty ( ) => true ,
96
+ _ => false ,
97
+ }
98
+ }
99
+
100
+ // Validates the presence and content of custom partition fields
101
+ // that it is not null, empty, or a floating-point number
86
102
pub fn validate_custom_partition (
87
103
value : & Map < String , Value > ,
88
104
custom_partition : Option < & String > ,
@@ -100,16 +116,6 @@ pub fn validate_custom_partition(
100
116
) ) ;
101
117
} ;
102
118
103
- fn is_null_or_empty ( value : & Value ) -> bool {
104
- match value {
105
- Value :: Null => true ,
106
- Value :: Object ( o) if o. is_empty ( ) => true ,
107
- Value :: Array ( a) if a. is_empty ( ) => true ,
108
- Value :: String ( s) if s. is_empty ( ) => true ,
109
- _ => false ,
110
- }
111
- }
112
-
113
119
if is_null_or_empty ( field_value) {
114
120
return Err ( JsonFlattenError :: FieldEmptyOrNull ( trimmed_field. to_owned ( ) ) ) ;
115
121
}
@@ -124,6 +130,8 @@ pub fn validate_custom_partition(
124
130
Ok ( ( ) )
125
131
}
126
132
133
+ // Validates time partitioning constraints, checking if a timestamp is a string
134
+ // that can be parsed as datetime within the configured time limit
127
135
pub fn validate_time_partition (
128
136
value : & Map < String , Value > ,
129
137
time_partition : Option < & String > ,
@@ -160,6 +168,8 @@ pub fn validate_time_partition(
160
168
}
161
169
}
162
170
171
+ // Flattens starting from only object types at TOP, e.g. with the parent_key `root` and separator `_`
172
+ // `{ "a": { "b": 1, c: { "d": 2 } } }` becomes `{"root_a_b":1,"root_a_c_d":2}`
163
173
pub fn flatten_with_parent_prefix (
164
174
nested_value : & mut Value ,
165
175
prefix : & str ,
@@ -176,7 +186,8 @@ pub fn flatten_with_parent_prefix(
176
186
Ok ( ( ) )
177
187
}
178
188
179
- pub fn flatten_object (
189
+ // Flattens a nested JSON Object/Map into another target Map
190
+ fn flatten_object (
180
191
output_map : & mut Map < String , Value > ,
181
192
parent_key : Option < & str > ,
182
193
nested_map : & mut Map < String , Value > ,
@@ -203,6 +214,7 @@ pub fn flatten_object(
203
214
Ok ( ( ) )
204
215
}
205
216
217
+ // Flattens a nested JSON Array into the parent Map
206
218
pub fn flatten_array_objects (
207
219
output_map : & mut Map < String , Value > ,
208
220
parent_key : & str ,
@@ -248,6 +260,16 @@ pub fn flatten_array_objects(
248
260
Ok ( ( ) )
249
261
}
250
262
263
+ /// Recursively flattens a JSON value.
264
+ /// - If the value is an array, it flattens all elements of the array.
265
+ /// - If the value is an object, it flattens all nested objects and arrays.
266
+ /// - Otherwise, it returns the value itself in a vector.
267
+ ///
268
+ /// Examples:
269
+ /// 1. `{"a": 1}` ~> `[{"a": 1}]`
270
+ /// 2. `[{"a": 1}, {"b": 2}]` ~> `[{"a": 1}, {"b": 2}]`
271
+ /// 3. `[{"a": [{"b": 1}, {"c": 2}]}]` ~> `[{"a": {"b": 1)}}, {"a": {"c": 2)}}]`
272
+ /// 3. `{"a": [{"b": 1}, {"c": 2}], "d": {"e": 4}}` ~> `[{"a": {"b":1}, "d": {"e":4}}, {"a": {"c":2}, "d": {"e":4}}]`
251
273
pub fn flatten_json ( value : & Value ) -> Vec < Value > {
252
274
match value {
253
275
Value :: Array ( arr) => arr. iter ( ) . flat_map ( flatten_json) . collect ( ) ,
@@ -290,6 +312,7 @@ pub fn flatten_json(value: &Value) -> Vec<Value> {
290
312
}
291
313
}
292
314
315
+ // Converts a Vector of values into a `Value::Array`, as long as all of them are objects
293
316
pub fn convert_to_array ( flattened : Vec < Value > ) -> Result < Value , JsonFlattenError > {
294
317
let mut result = Vec :: new ( ) ;
295
318
for item in flattened {
0 commit comments