Skip to main content

solidity_language_server/
utils.rs

1pub fn byte_offset_to_position(source: &str, byte_offset: usize) -> (u32, u32) {
2    let mut line = 0;
3    let mut col = 0;
4    let mut i = 0;
5
6    let bytes = source.as_bytes();
7    while i < byte_offset && i < bytes.len() {
8        match bytes[i] {
9            b'\n' => {
10                line += 1;
11                col = 0;
12                i += 1;
13            }
14            b'\r' if i + 1 < bytes.len() && bytes[i + 1] == b'\n' => {
15                line += 1;
16                col = 0;
17                i += 2;
18            }
19            _ => {
20                col += 1;
21                i += 1;
22            }
23        }
24    }
25
26    (line, col)
27}
28
29pub fn position_to_byte_offset(source: &str, line: u32, character: u32) -> usize {
30    let mut current_line = 0;
31    let mut current_col = 0;
32
33    for (i, ch) in source.char_indices() {
34        if current_line == line && current_col == character {
35            return i;
36        }
37
38        match ch {
39            '\n' => {
40                if current_line == line && current_col < character {
41                    return i; // clamp to end of line
42                }
43                current_line += 1;
44                current_col = 0;
45            }
46            _ => {
47                current_col += 1;
48            }
49        }
50    }
51
52    source.len()
53}
54
55pub fn is_valid_solidity_identifier(name: &str) -> bool {
56    if name.is_empty() {
57        return false;
58    }
59    let chars: Vec<char> = name.chars().collect();
60    let first = chars[0];
61    if !first.is_ascii_alphabetic() && first != '_' {
62        return false;
63    }
64    for &c in &chars {
65        if !c.is_ascii_alphanumeric() && c != '_' {
66            return false;
67        }
68    }
69    true
70}
71
72