parallel_disk_usage/visualizer/methods/
bar_table.rs

1use super::{NodeInfo, TreeRow, TreeTable};
2use crate::{size, visualizer::ProportionBar};
3use assert_cmp::debug_assert_op;
4use derive_more::{Deref, DerefMut};
5use std::{collections::LinkedList, fmt::Display};
6
7#[derive(Deref, DerefMut)]
8pub(super) struct BarRow<Name, NodeData> {
9    #[deref]
10    #[deref_mut]
11    pub(super) tree_row: TreeRow<Name, NodeData>,
12    pub(super) proportion_bar: ProportionBar,
13}
14
15pub(super) fn render_bars<'a, Name, Size>(
16    tree_table: TreeTable<&'a Name, Size>,
17    total: u64,
18    width: usize,
19) -> LinkedList<BarRow<&'a Name, Size>>
20where
21    Name: Display,
22    Size: size::Size + Into<u64> + 'a,
23{
24    tree_table
25        .data
26        .into_iter()
27        .map(|tree_row| {
28            let get_value = |node_info: &NodeInfo<&Name, Size>| {
29                let node_data = node_info.node_data.into();
30                if total == 0 {
31                    return 0;
32                }
33                rounded_div::u64(node_data * (width as u64), total) as usize
34            };
35
36            macro_rules! ancestor_value {
37                ($index:expr, $fallback:expr) => {
38                    tree_row.ancestors.get($index).map_or($fallback, get_value)
39                };
40            }
41
42            let lv0_value = get_value(&tree_row.node_info);
43            let lv1_value = ancestor_value!(3, lv0_value);
44            let lv2_value = ancestor_value!(2, lv1_value);
45            let lv3_value = ancestor_value!(1, lv2_value);
46            let lv4_value = width;
47            debug_assert_op!(lv0_value <= lv1_value);
48            debug_assert_op!(lv1_value <= lv2_value);
49            debug_assert_op!(lv2_value <= lv3_value);
50            debug_assert_op!(lv3_value <= lv4_value);
51
52            let lv0_visible = lv0_value;
53            let lv1_visible = lv1_value - lv0_value;
54            let lv2_visible = lv2_value - lv1_value;
55            let lv3_visible = lv3_value - lv2_value;
56            let lv4_visible = lv4_value - lv3_value;
57
58            #[cfg(debug_assertions)]
59            {
60                let actual_lv4_value = ancestor_value!(0, lv3_value);
61                if actual_lv4_value != 0 {
62                    debug_assert_op!(actual_lv4_value == width);
63                    assert_cmp::debug_assert_op_expr!(
64                        lv0_visible + lv1_visible + lv2_visible + lv3_visible + lv4_visible,
65                        ==,
66                        width
67                    );
68                }
69            }
70
71            let proportion_bar = ProportionBar {
72                level0: lv0_visible,
73                level1: lv1_visible,
74                level2: lv2_visible,
75                level3: lv3_visible,
76                level4: lv4_visible,
77            };
78            BarRow {
79                tree_row,
80                proportion_bar,
81            }
82        })
83        .collect()
84}