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
use crate::apply_filter::apply_filter;
use crate::flatten_json_array::flatten_json_array;
use crate::get_selection::get_selection;
use crate::truncate::truncate_json;
use crate::types::{Group, MaybeArray, Selection};
use serde_json::json;
use serde_json::Value;
/// Walks through a group.
pub fn group_walker(
(spread, root, selectors, filters, truncate): &Group,
json: &Value,
) -> Selection {
// Empty group, return early.
if selectors.is_empty() && root.is_none() {
return Err(String::from("Empty group"));
}
match get_selection(&selectors, &json) {
Ok(ref items) => {
// Check for an empty selection, in this case we assume that the
// user expects to get back the complete raw JSON for this group.
let output_json = if items.is_empty() {
json.clone()
} else {
json!(items.last())
};
let is_spreading = spread.is_some();
let output = match apply_filter(&filters, &output_json) {
Ok(filtered) => match filtered {
MaybeArray::Array(array) => Ok(if is_spreading {
flatten_json_array(&json!(array))
} else {
json!(array)
}),
MaybeArray::NonArray(single_value) => {
if is_spreading {
Err(String::from("Only arrays can be flattened"))
} else {
// We know that we are holding a single value
// wrapped inside a MaybeArray::NonArray enum.
// We need to pick the first item of the vector.
Ok(json!(single_value[0]))
}
}
},
Err(error) => Err(error),
};
match truncate {
Some(_) => match output {
Ok(value) => Ok(truncate_json(value)),
Err(error) => Err(error),
},
None => output,
}
}
Err(items) => Err(items),
}
}