Add Rope::depth()

This commit is contained in:
Matthew Gordon 2024-10-19 15:00:57 -03:00
parent a22968456c
commit 3873e5561f
1 changed files with 101 additions and 0 deletions

View File

@ -157,6 +157,21 @@ impl Rope {
self self
} }
/// Number of steps between this node and it's most distance descendant
///
/// Leaf nodes have a depth of 0 and each branch node has a depth one
/// greater than the depth of deepest child.
pub fn depth(&self) -> usize {
match self {
Rope::Branch { left, right, .. } => {
left.depth()
.max(right.as_ref().map(|r| r.depth()).unwrap_or(0))
+ 1
}
Rope::Leaf { .. } => 0,
}
}
/// Returns true if this node is a leaf node, false otherwise /// Returns true if this node is a leaf node, false otherwise
pub fn is_leaf(&self) -> bool { pub fn is_leaf(&self) -> bool {
match &self { match &self {
@ -321,6 +336,22 @@ mod tests {
"aあbcdeえfghiいjklmnおopqrstuうvwxyz" "aあbcdeえfghiいjklmnおopqrstuうvwxyz"
} }
impl Rope {
fn unwrap_branch_left(&self) -> &Rc<Rope> {
match self {
Rope::Branch { left, .. } => left,
Rope::Leaf { .. } => panic!("Expected branch node but found leaf"),
}
}
fn unwrap_branch_right(&self) -> Option<&Rc<Rope>> {
match self {
Rope::Branch { right, .. } => right.as_ref(),
Rope::Leaf { .. } => panic!("Expected branch node but found leaf"),
}
}
}
#[test] #[test]
#[timeout(100)] #[timeout(100)]
fn node_iterator_for_single_node_returns_node_and_only_node() { fn node_iterator_for_single_node_returns_node_and_only_node() {
@ -398,4 +429,74 @@ mod tests {
assert_eq!(string, expected); assert_eq!(string, expected);
} }
} }
#[test]
fn depths_have_correct_values() {
let target = small_test_rope_with_multibyte_chars();
assert_eq!(target.depth(), 4);
assert_eq!(target.unwrap_branch_left().depth(), 2);
assert_eq!(target.unwrap_branch_left().unwrap_branch_left().depth(), 1);
assert_eq!(
target
.unwrap_branch_left()
.unwrap_branch_left()
.unwrap_branch_left()
.depth(),
0
);
assert_eq!(
target
.unwrap_branch_left()
.unwrap_branch_left()
.unwrap_branch_right()
.unwrap()
.depth(),
0
);
assert_eq!(
target
.unwrap_branch_left()
.unwrap_branch_right()
.unwrap()
.depth(),
1
);
assert_eq!(
target
.unwrap_branch_left()
.unwrap_branch_right()
.unwrap()
.unwrap_branch_left()
.depth(),
0
);
assert_eq!(
target
.unwrap_branch_left()
.unwrap_branch_right()
.unwrap()
.unwrap_branch_right()
.unwrap()
.depth(),
0
);
assert_eq!(target.unwrap_branch_right().unwrap().depth(), 3);
assert_eq!(
target
.unwrap_branch_right()
.unwrap()
.unwrap_branch_left()
.depth(),
2
);
assert_eq!(
target
.unwrap_branch_right()
.unwrap()
.unwrap_branch_right()
.unwrap()
.depth(),
1
);
}
} }