Skip to main content

pacenotes_installer\tree/
arena.rs

1/// Nodes in a flat arena, so a node's index can ride in a tree view item's `lParam`.
2#[derive(Clone, Debug, Default)]
3pub struct Tree {
4    pub(super) nodes: Vec<super::Node>,
5    /// The top-level category rows, in display order.
6    pub(super) roots: Vec<usize>,
7}
8
9impl Tree {
10    pub fn is_empty(&self) -> bool {
11        self.nodes.is_empty()
12    }
13
14    pub fn len(&self) -> usize {
15        self.nodes.len()
16    }
17
18    pub fn node(&self, index: usize) -> &super::Node {
19        &self.nodes[index]
20    }
21
22    pub fn roots(&self) -> &[usize] {
23        &self.roots
24    }
25
26    pub fn children(&self, index: usize) -> &[usize] {
27        &self.nodes[index].children
28    }
29
30    /// Labels from the category row down to `index`, inclusive.
31    pub fn path_of(&self, index: usize) -> Vec<&str> {
32        let mut labels = Vec::new();
33        let mut current = Some(index);
34        while let Some(node) = current {
35            labels.push(self.nodes[node].label.as_str());
36            current = self.nodes[node].parent;
37        }
38        labels.reverse();
39        labels
40    }
41
42    /// The category as the server spells it, for comparing with `CATEGORY_*`.
43    pub fn category_of(&self, index: usize) -> &str {
44        let mut current = index;
45        while let Some(parent) = self.nodes[current].parent {
46            current = parent;
47        }
48        &self.nodes[current].label
49    }
50
51    /// Every leaf under `index`, or in the whole tree for `None`, in display order.
52    pub fn leaves_under(&self, index: Option<usize>) -> Vec<usize> {
53        let mut leaves = Vec::new();
54        match index {
55            Some(index) => self.collect_leaves(index, &mut leaves),
56            None => {
57                for &root in &self.roots {
58                    self.collect_leaves(root, &mut leaves);
59                }
60            }
61        }
62        leaves
63    }
64
65    fn collect_leaves(&self, index: usize, leaves: &mut Vec<usize>) {
66        if self.nodes[index].is_leaf() {
67            leaves.push(index);
68            return;
69        }
70        for &child in &self.nodes[index].children {
71            self.collect_leaves(child, leaves);
72        }
73    }
74
75    pub(super) fn push(&mut self, node: super::Node, parent: Option<usize>) -> usize {
76        let index = self.nodes.len();
77        self.nodes.push(node);
78        match parent {
79            Some(parent) => self.nodes[parent].children.push(index),
80            None => self.roots.push(index),
81        }
82        index
83    }
84}