diff --git a/src/write_zipper.rs b/src/write_zipper.rs index 0892e475..86716f7c 100644 --- a/src/write_zipper.rs +++ b/src/write_zipper.rs @@ -2572,6 +2572,9 @@ impl <'a, 'path, V: Clone + Send + Sync + Unpin, A: Allocator + 'a> WriteZipperC if should_ascend { self.key.prefix_buf.truncate(temp_path.len()); + } else if ascended { + //The zipper didn't move, so restore the node stack to the focus + self.descend_to_internal(); } pruned_bytes @@ -3710,6 +3713,50 @@ mod tests { assert_eq!(btm2.path_exists_at(&[0, 255, 1]), false); } + /// A write after `prune_path` (or `meet_into(.., true)`) must reach the focus node + #[test] + fn write_zipper_write_after_prune_path_below_a_graft() { + let build = || { + let mut m0 = PathMap::::new(); + let mut m1 = PathMap::::new(); + m1.set_val_at(&[1u8, 0, 0, 0, 0], 7); + m0.create_path(&[0u8, 0]); + m1.create_path(&[1u8]); + (m0, m1) + }; + + // prune_path directly + let (mut m0, m1) = build(); + { + let mut wz = m0.write_zipper_at_path(&[0u8, 0]); + let rz = m1.read_zipper_at_path(&[1u8]); + wz.graft(&rz); + wz.descend_last_byte(); + wz.remove_branches(false); + wz.prune_path(); + assert_eq!(wz.path(), &[0u8]); + assert_eq!(*wz.get_val_or_set_mut_with(|| 3), 3); + assert_eq!(wz.val(), Some(&3)); + } + assert_eq!(m0.get_val_at(&[0u8, 0, 0]), Some(&3)); + assert_eq!(m0.val_count(), 1); + + // through meet_into with prune + let (mut m0, m1) = build(); + { + let mut wz = m0.write_zipper_at_path(&[0u8, 0]); + let rz = m1.read_zipper_at_path(&[1u8]); + wz.graft(&rz); + wz.descend_last_byte(); + wz.meet_into(&rz, true); + assert_eq!(wz.path(), &[0u8]); + assert_eq!(*wz.get_val_or_set_mut_with(|| 3), 3); + assert_eq!(wz.val(), Some(&3)); + } + assert_eq!(m0.get_val_at(&[0u8, 0, 0]), Some(&3)); + } + + /// Tests whether the [WriteZipper::subtract_into] operation will do the right thing with the root value #[test] fn write_zipper_subtract_into_test1() {