luaur_analysis/functions/
get_document_offsets.rs1use luaur_ast::records::position::Position;
2
3pub(crate) fn get_document_offsets(
4 src: &str,
5 start_pos: &Position,
6 end_pos: &Position,
7) -> (usize, usize) {
8 let mut line_count: u32 = 0;
9 let mut col_count: u32 = 0;
10
11 let mut doc_offset: usize = 0;
12 let mut start_offset: usize = 0;
13 let mut end_offset: usize = 0;
14 let mut found_start = false;
15 let mut found_end = false;
16
17 for c in src.chars() {
18 if found_start && found_end {
19 break;
20 }
21
22 if start_pos.line == line_count && start_pos.column == col_count {
23 found_start = true;
24 start_offset = doc_offset;
25 }
26
27 if end_pos.line == line_count && end_pos.column == col_count {
28 end_offset = doc_offset;
29 found_end = true;
30 }
31
32 if found_start && !found_end && (line_count > end_pos.line) {
34 found_end = true;
35 end_offset = doc_offset.saturating_sub(1);
36 }
37
38 if c == '\n' {
39 line_count += 1;
40 col_count = 0;
41 } else {
42 col_count += 1;
43 }
44 doc_offset += c.len_utf8();
45 }
46
47 if found_start && !found_end {
48 end_offset = src.len();
49 }
50
51 let min = core::cmp::min(start_offset, end_offset);
52 let max = core::cmp::max(start_offset, end_offset);
53 let len = max - min;
54
55 (min, len)
56}