1use super::*;
2
3pub trait PointExt {
4 #[must_use]
5 fn advance(self, delta: Point) -> Self;
6 fn position(&self, document: &Document) -> lsp::Position;
7}
8
9impl PointExt for Point {
10 fn advance(self, delta: Point) -> Self {
13 if delta.row == 0 {
14 Point::new(self.row, self.column + delta.column)
15 } else {
16 Point::new(self.row + delta.row, delta.column)
17 }
18 }
19
20 fn position(&self, document: &Document) -> lsp::Position {
26 let line = document.content.line(self.row);
27
28 let utf16_cu = line.char_to_utf16_cu(line.byte_to_char(self.column));
29
30 lsp::Position {
31 line: u32::try_from(self.row).expect("line index exceeds u32::MAX"),
32 character: u32::try_from(utf16_cu)
33 .expect("column index exceeds u32::MAX"),
34 }
35 }
36}
37
38#[cfg(test)]
39mod tests {
40 use {super::*, pretty_assertions::assert_eq};
41
42 #[test]
43 fn advance_adds_columns_when_staying_on_same_row() {
44 assert_eq!(Point::new(2, 3).advance(Point::new(0, 5)), Point::new(2, 8));
45 }
46
47 #[test]
48 fn advance_moves_rows_and_resets_column_when_row_delta_positive() {
49 assert_eq!(Point::new(1, 4).advance(Point::new(2, 3)), Point::new(3, 3));
50 }
51
52 #[test]
53 fn converts_utf8_columns_to_utf16_offsets() {
54 let document = Document::from("a𐐀b");
55
56 assert_eq!(
57 Point::new(0, document.content.line(0).char_to_byte(2))
58 .position(&document),
59 lsp::Position {
60 line: 0,
61 character: 3
62 }
63 );
64 }
65}