pipeline_script/lexer/
position.rs

1use std::ops::{Add, AddAssign};
2use std::string::ToString;
3
4#[derive(Debug, Clone)]
5pub struct Position {
6    pub(crate) pos: usize,
7    #[allow(unused)]
8    pub(crate) row: usize,
9    #[allow(unused)]
10    pub(crate) col: usize,
11    pub(crate) span: usize,
12    pub module_name: String,
13}
14
15impl Add for Position {
16    type Output = Position;
17
18    fn add(self, rhs: Self) -> Self::Output {
19        let mut pos = self.clone();
20        pos.span = rhs.pos.abs_diff(self.pos) + rhs.span;
21        pos
22    }
23}
24impl AddAssign for Position {
25    fn add_assign(&mut self, rhs: Self) {
26        self.span = rhs.pos.abs_diff(self.pos) + rhs.span;
27    }
28}
29impl Position {
30    pub fn none() -> Self {
31        Self {
32            pos: 0,
33            span: 0,
34            row: 0,
35            col: 0,
36            module_name: "None".to_string(),
37        }
38    }
39    pub fn new(pos: usize, span: usize, row: usize, col: usize, module_name: &str) -> Self {
40        Self {
41            pos,
42            span,
43            row,
44            col,
45            module_name: module_name.into(),
46        }
47    }
48    #[allow(unused)]
49    pub fn set_span(&mut self, span: usize) {
50        self.span = span;
51    }
52    #[allow(unused)]
53    pub fn set_pos(&mut self, pos: usize) {
54        self.pos = pos;
55    }
56    #[allow(unused)]
57    pub fn add_span(&mut self, add: usize) {
58        self.span += add
59    }
60    #[allow(unused)]
61    pub fn is_none(&self) -> bool {
62        if self.pos == 0 && self.span == 0 {
63            return true;
64        }
65        false
66    }
67    #[allow(unused)]
68    pub fn get_raw_string(&self, source: &[char]) -> String {
69        let utf8_bytes = source[self.pos..self.pos + self.span]
70            .iter()
71            .flat_map(|&c| c.encode_utf8(&mut [0; 4]).bytes().collect::<Vec<_>>())
72            .collect::<Vec<_>>();
73        String::from_utf8(utf8_bytes).unwrap()
74    }
75    #[allow(unused)]
76    pub fn get_row_col(&self, source: &[char]) -> (usize, usize) {
77        let mut row = 0;
78        let mut col = 0;
79        for (i, &ch) in source.iter().enumerate() {
80            // 如果已经到达或超过pos指定的位置,则退出循环
81            if i >= self.pos {
82                break;
83            }
84            // 如果遇到换行符,则行数增加,列数重置(除非换行符是最后一个字符)
85            if ch == '\n' {
86                row += 1;
87                col = 0;
88            } else {
89                col += 1;
90            }
91        }
92        // 由于循环在到达pos时退出,我们需要检查最后一个字符是否是换行符
93        // 如果是,则实际的列数应该是换行符之前的列数
94        if let Some(&last_char) = source.get(self.pos - 1) {
95            if last_char == '\n' {
96                col = 0;
97            }
98        }
99        // 返回计算出的行和列
100        (row, col)
101    }
102}