Skip to main content

luaur_analysis/functions/
get_document_offsets.rs

1use 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        // We put a cursor position that extends beyond the extents of the current line
33        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}