ziyy_core/common/
position.rs

1use std::{
2    fmt::Display,
3    ops::{AddAssign, SubAssign},
4};
5
6#[derive(Debug, Clone, Copy, PartialEq)]
7/// A position in source code.
8pub struct Position {
9    /// Line in source code.
10    pub line: i32,
11    /// Column in source code.
12    pub column: i32,
13}
14
15impl Default for Position {
16    fn default() -> Self {
17        Self { line: 1, column: 1 }
18    }
19}
20
21impl Position {
22    /// Creates a new Position.
23    pub fn new(line: i32, column: i32) -> Self {
24        Self { line, column }
25    }
26}
27
28impl AddAssign<(i32, i32)> for Position {
29    fn add_assign(&mut self, rhs: (i32, i32)) {
30        let (line, column) = rhs;
31        self.line += line;
32        if line > 0 {
33            self.column = 1;
34        } else {
35            self.column += column;
36        }
37    }
38}
39
40impl SubAssign<(i32, i32)> for Position {
41    fn sub_assign(&mut self, rhs: (i32, i32)) {
42        let (line, column) = rhs;
43        self.line -= line;
44        self.column -= column;
45    }
46}
47
48impl PartialOrd for Position {
49    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
50        match self.line.partial_cmp(&other.line) {
51            Some(core::cmp::Ordering::Equal) => {}
52            ord => return ord,
53        }
54        self.column.partial_cmp(&other.column)
55    }
56}
57
58impl Display for Position {
59    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60        if f.alternate() {
61            f.write_fmt(format_args!("({},{})", self.line, self.column))
62        } else {
63            f.write_fmt(format_args!("{}:{}", self.line, self.column))
64        }
65    }
66}