1use alloc::boxed::Box;
8use alloc::vec::Vec;
9
10use crate::bounds::{Bounds, union_all};
11use crate::indexable::Indexable;
12
13#[derive(Debug)]
19pub enum Node<T> {
20 Leaf(Vec<T>),
22 Branch(Vec<(Bounds, Box<Node<T>>)>),
24}
25
26impl<T: Indexable> Node<T> {
27 #[must_use]
30 pub fn bounds(&self) -> Option<Bounds> {
31 match self {
32 Node::Leaf(values) => {
33 if values.is_empty() {
34 None
35 } else {
36 let boxes: Vec<Bounds> = values.iter().map(Indexable::bounds).collect();
37 Some(union_all(&boxes))
38 }
39 }
40 Node::Branch(children) => {
41 if children.is_empty() {
42 None
43 } else {
44 let boxes: Vec<Bounds> = children.iter().map(|(b, _)| *b).collect();
45 Some(union_all(&boxes))
46 }
47 }
48 }
49 }
50
51 #[must_use]
54 pub fn entry_count(&self) -> usize {
55 match self {
56 Node::Leaf(values) => values.len(),
57 Node::Branch(children) => children.len(),
58 }
59 }
60
61 #[must_use]
63 pub fn value_count(&self) -> usize {
64 match self {
65 Node::Leaf(values) => values.len(),
66 Node::Branch(children) => children.iter().map(|(_, c)| c.value_count()).sum(),
67 }
68 }
69
70 #[must_use]
72 pub fn height(&self) -> usize {
73 match self {
74 Node::Leaf(_) => 1,
75 Node::Branch(children) => {
76 1 + children.iter().map(|(_, c)| c.height()).max().unwrap_or(0)
77 }
78 }
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::Node;
85 use crate::bounds::Bounds;
86 use alloc::boxed::Box;
87
88 #[test]
89 fn leaf_bounds_union_of_values() {
90 let leaf: Node<Bounds> = Node::Leaf(alloc::vec![
91 Bounds::point([0.0, 0.0]),
92 Bounds::point([2.0, 3.0]),
93 ]);
94 assert_eq!(leaf.bounds(), Some(Bounds::new([0.0, 0.0], [2.0, 3.0])));
95 assert_eq!(leaf.entry_count(), 2);
96 assert_eq!(leaf.height(), 1);
97 }
98
99 #[test]
100 fn branch_bounds_and_height() {
101 let leaf_a: Node<Bounds> = Node::Leaf(alloc::vec![Bounds::point([0.0, 0.0])]);
102 let leaf_b: Node<Bounds> = Node::Leaf(alloc::vec![Bounds::point([5.0, 5.0])]);
103 let branch: Node<Bounds> = Node::Branch(alloc::vec![
104 (leaf_a.bounds().unwrap(), Box::new(leaf_a)),
105 (leaf_b.bounds().unwrap(), Box::new(leaf_b)),
106 ]);
107 assert_eq!(branch.bounds(), Some(Bounds::new([0.0, 0.0], [5.0, 5.0])));
108 assert_eq!(branch.height(), 2);
109 assert_eq!(branch.value_count(), 2);
110 }
111
112 #[test]
113 fn empty_leaf_has_no_bounds() {
114 let leaf: Node<Bounds> = Node::Leaf(alloc::vec![]);
115 assert_eq!(leaf.bounds(), None);
116 }
117}