From 5f93d7f755dbf6a86b1c735ce3343f15d7fd2939 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sat, 15 May 2021 11:43:29 +0200 Subject: [PATCH] Return error in `Rope::to_offset(point)` when the point doesn't exist --- zed/src/editor/buffer/rope.rs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/zed/src/editor/buffer/rope.rs b/zed/src/editor/buffer/rope.rs index 78ed156308..0dec8fbc14 100644 --- a/zed/src/editor/buffer/rope.rs +++ b/zed/src/editor/buffer/rope.rs @@ -136,12 +136,14 @@ impl Rope { } pub fn to_offset(&self, point: Point) -> Result { - // TODO: Verify the point actually exists. if point <= self.summary().lines { let mut cursor = self.chunks.cursor::(); cursor.seek(&point, SeekBias::Left, &()); let overshoot = point - cursor.start().lines; - Ok(cursor.start().chars + cursor.item().map_or(0, |chunk| chunk.to_offset(overshoot))) + Ok(cursor.start().chars + + cursor + .item() + .map_or(Ok(0), |chunk| chunk.to_offset(overshoot))?) } else { Err(anyhow!("offset out of bounds")) } @@ -263,7 +265,7 @@ impl Chunk { point } - fn to_offset(&self, target: Point) -> usize { + fn to_offset(&self, target: Point) -> Result { let mut offset = 0; let mut point = Point::new(0, 0); for ch in self.0.chars() { @@ -279,7 +281,12 @@ impl Chunk { } offset += 1; } - offset + + if point == target { + Ok(offset) + } else { + Err(anyhow!("point out of bounds")) + } } } @@ -515,6 +522,10 @@ mod tests { assert_eq!(actual.to_point(offset).unwrap(), point); assert_eq!(actual.to_offset(point).unwrap(), offset); if ch == '\n' { + assert!(actual + .to_offset(Point::new(point.row, point.column + 1)) + .is_err()); + point.row += 1; point.column = 0 } else { @@ -522,6 +533,10 @@ mod tests { } offset += 1; } + assert_eq!(actual.to_point(offset).unwrap(), point); + assert!(actual.to_point(offset + 1).is_err()); + assert_eq!(actual.to_offset(point).unwrap(), offset); + assert!(actual.to_offset(Point::new(point.row + 1, 0)).is_err()); for _ in 0..5 { let end_ix = rng.gen_range(0..=expected.chars().count());