Skip to main content

osp_cli/dsl/stages/
collapse.rs

1use 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}