diff --git a/crates/rle/src/range_map.rs b/crates/rle/src/range_map.rs index c34be37d..89d60ae7 100644 --- a/crates/rle/src/range_map.rs +++ b/crates/rle/src/range_map.rs @@ -65,7 +65,7 @@ impl RangeMap self.tree.with_tree_mut(|tree| { tree.delete_range( Some(start), - Some(start + Index::from_usize(value.len()).unwrap()), + Some(start + Index::from_usize(std::cmp::max(value.len(), 1)).unwrap()), ); tree.insert( start, diff --git a/crates/rle/src/rle_tree/node/leaf_impl.rs b/crates/rle/src/rle_tree/node/leaf_impl.rs index 8391984e..7c4c7a3f 100644 --- a/crates/rle/src/rle_tree/node/leaf_impl.rs +++ b/crates/rle/src/rle_tree/node/leaf_impl.rs @@ -295,6 +295,10 @@ impl<'a, T: Rle, A: RleTreeTrait> LeafNode<'a, T, A> { where F: FnMut(&T, *mut LeafNode<'_, T, A>), { + if self.children.is_empty() { + return Ok(()); + } + let (del_start, del_relative_from) = start.map_or((0, None), |x| self._delete_start(x)); let (del_end, del_relative_to) = end.map_or((self.children.len(), None), |x| self._delete_end(x)); diff --git a/crates/rle/src/rle_tree/test/notify_test.rs b/crates/rle/src/rle_tree/test/notify_test.rs index 6c74617c..74ce7513 100644 --- a/crates/rle/src/rle_tree/test/notify_test.rs +++ b/crates/rle/src/rle_tree/test/notify_test.rs @@ -118,8 +118,10 @@ fn test(interactions: &[Interaction]) { let range_map_out = range_map_output.unwrap(); let range = range_map_out.start..range_map_out.end; assert!( - range.contains(&id) - && range.contains(&(origin_value.value + origin_value.len() as u64 - 1)), + (origin_value.len() == 0 && origin_value.value == range.start) + || (range.contains(&id) + && range + .contains(&(origin_value.value + origin_value.len() as u64 - 1))), "origin={:#?}, range={:#?}", origin_value, range @@ -146,7 +148,7 @@ prop_compose! { fn gen_interaction()( _type in 0..2, from in 0..1000, - len in 1..10, + len in 0..10, ) -> Interaction { if _type == 0 { Interaction::Insert { @@ -204,25 +206,9 @@ fn issue_4() { #[test] fn issue_5() { test(&[ - Insert { from: 0, len: 4 }, - Insert { from: 0, len: 5 }, - Delete { from: 3, len: 1 }, - Delete { from: 5, len: 3 }, - Insert { from: 3, len: 6 }, - Insert { from: 3, len: 8 }, - Delete { from: 13, len: 6 }, - Insert { from: 3, len: 1 }, - Insert { from: 1, len: 2 }, - Delete { from: 0, len: 2 }, - Delete { from: 0, len: 1 }, - Insert { from: 8, len: 3 }, - Delete { from: 11, len: 2 }, - Insert { from: 2, len: 1 }, - Delete { from: 8, len: 2 }, - Insert { from: 11, len: 1 }, - Delete { from: 11, len: 2 }, - Insert { from: 9, len: 1 }, - Delete { from: 1, len: 3 }, + Insert { from: 0, len: 0 }, + Delete { from: 0, len: 0 }, + Delete { from: 0, len: 0 }, ]) } diff --git a/crates/rle/src/rle_tree/tree_trait.rs b/crates/rle/src/rle_tree/tree_trait.rs index ac4847e0..cf92a3ab 100644 --- a/crates/rle/src/rle_tree/tree_trait.rs +++ b/crates/rle/src/rle_tree/tree_trait.rs @@ -111,6 +111,10 @@ impl RleTreeTrait for CumulateTreeTrait, mut index: Self::Int, ) -> FindPosResult { + if node.children.is_empty() { + return FindPosResult::new(0, 0, Position::Before); + } + let mut last_cache = 0; for (i, child) in node.children().iter().enumerate() { last_cache = match child { @@ -139,6 +143,10 @@ impl RleTreeTrait for CumulateTreeTrait, mut index: Self::Int) -> FindPosResult { + if node.children.is_empty() { + return FindPosResult::new(0, 0, Position::Before); + } + for (i, child) in node.children().iter().enumerate() { if index < HasLength::len(&**child) { return FindPosResult::new(i, index, get_pos(index, child.len()));