osp_cli/dsl/stages/
collapse.rs1use crate::core::{
2 output_model::{Group, OutputItems},
3 row::Row,
4};
5
6pub fn apply(items: OutputItems) -> OutputItems {
7 match items {
8 OutputItems::Rows(rows) => OutputItems::Rows(rows),
9 OutputItems::Groups(groups) => {
10 let collapsed = groups.into_iter().map(collapse_group).collect();
11 OutputItems::Rows(collapsed)
12 }
13 }
14}
15
16fn collapse_group(group: Group) -> Row {
17 let mut summary = Row::new();
18 summary.extend(group.groups);
19 summary.extend(group.aggregates);
20 summary
21}
22
23#[cfg(test)]
24mod tests {
25 use crate::core::output_model::{Group, OutputItems};
26 use serde_json::json;
27
28 use super::apply;
29
30 #[test]
31 fn passes_through_rows_unchanged() {
32 let rows = vec![
33 json!({"uid": "oistes"})
34 .as_object()
35 .cloned()
36 .expect("object"),
37 ];
38
39 let output = apply(OutputItems::Rows(rows.clone()));
40 assert_eq!(output, OutputItems::Rows(rows));
41 }
42
43 #[test]
44 fn collapses_groups_into_summary_rows() {
45 let groups = vec![Group {
46 groups: json!({"dept": "Sales"})
47 .as_object()
48 .cloned()
49 .expect("object"),
50 aggregates: json!({"member_count": 2})
51 .as_object()
52 .cloned()
53 .expect("object"),
54 rows: Vec::new(),
55 }];
56
57 let output = apply(OutputItems::Groups(groups));
58 match output {
59 OutputItems::Rows(rows) => {
60 assert_eq!(rows.len(), 1);
61 assert_eq!(rows[0].get("dept").and_then(|v| v.as_str()), Some("Sales"));
62 assert_eq!(
63 rows[0].get("member_count").and_then(|v| v.as_i64()),
64 Some(2)
65 );
66 }
67 OutputItems::Groups(_) => panic!("collapse must return rows"),
68 }
69 }
70}