From 3873e5561fed6f0bf1b1481592883043cc95e299 Mon Sep 17 00:00:00 2001 From: Matthew Gordon Date: Sat, 19 Oct 2024 15:00:57 -0300 Subject: [PATCH] Add Rope::depth() --- src/core/rope.rs | 101 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/src/core/rope.rs b/src/core/rope.rs index 92c82dd..80e7492 100644 --- a/src/core/rope.rs +++ b/src/core/rope.rs @@ -157,6 +157,21 @@ impl Rope { 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 pub fn is_leaf(&self) -> bool { match &self { @@ -321,6 +336,22 @@ mod tests { "aあbcdeえfghiいjklmnおopqrstuうvwxyz" } + impl Rope { + fn unwrap_branch_left(&self) -> &Rc { + match self { + Rope::Branch { left, .. } => left, + Rope::Leaf { .. } => panic!("Expected branch node but found leaf"), + } + } + + fn unwrap_branch_right(&self) -> Option<&Rc> { + match self { + Rope::Branch { right, .. } => right.as_ref(), + Rope::Leaf { .. } => panic!("Expected branch node but found leaf"), + } + } + } + #[test] #[timeout(100)] fn node_iterator_for_single_node_returns_node_and_only_node() { @@ -398,4 +429,74 @@ mod tests { 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 + ); + } }