Skip to main content

rexlang_lexer/
span.rs

1//! The Span module defines source positions, and ranges of source positions,
2//! in which nodes can be defined. It is used to link nodes back to their
3//! origins in the source.
4
5use std::fmt::{self, Display, Formatter};
6
7/// A Position represents an arbitrary source position. It includes the line
8/// number, and column number.
9#[derive(
10    Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, serde::Deserialize, serde::Serialize,
11)]
12#[serde(rename_all = "lowercase")]
13pub struct Position {
14    pub line: usize,
15    pub column: usize,
16}
17
18impl Position {
19    /// Create a new Position.
20    ///
21    /// # Arguments
22    /// * `line` The line number, where the first line of the file is at zero.
23    /// * `column` The column number, where the first column of a line is at
24    ///   zero.
25    ///
26    /// # Return
27    /// A new Position.
28    pub fn new(line: usize, column: usize) -> Position {
29        Position { line, column }
30    }
31
32    /// # Return
33    /// The line number of the Position.
34    pub fn line(&self) -> usize {
35        self.line
36    }
37
38    /// # Return
39    /// The column number of the Position.
40    pub fn column(&self) -> usize {
41        self.column
42    }
43}
44
45impl fmt::Display for Position {
46    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
47        write!(formatter, "{}:{}", self.line, self.column)
48    }
49}
50
51/// A Span represents an arbitrary source range. It includes the beginning and
52/// ending Positions.
53#[derive(
54    Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, serde::Deserialize, serde::Serialize,
55)]
56#[serde(rename_all = "lowercase")]
57pub struct Span {
58    pub begin: Position,
59    pub end: Position,
60}
61
62impl Span {
63    /// Create a new Span. The beginning and ending Positions will also be
64    /// created.
65    ///
66    /// # Arguments
67    /// * `begin_line` The line number for the beginning of the Span, where the
68    ///   first line of the file is at zero.
69    /// * `begin_column` The column number for the beginning of the Span, where
70    ///   the first column of a line is at zero.
71    /// * `end_line` The line number for the ending of the Span, where the first
72    ///   line of the file is at zero.
73    /// * `end_column` The column number for the ending of the Span, where the
74    ///   first column of a line is at zero.
75    ///
76    /// # Return
77    /// A new Span, with new beginning and ending Positions.
78    pub fn new(begin_line: usize, begin_column: usize, end_line: usize, end_column: usize) -> Self {
79        Self {
80            begin: Position::new(begin_line, begin_column),
81            end: Position::new(end_line, end_column),
82        }
83    }
84
85    /// Create a new Span from beginning and ending positions.
86    ///
87    /// # Arguments
88    /// * `begin` The beginning position.
89    /// * `end` The ending position.
90    ///
91    /// # Return
92    /// A new Span, with the beginning and ending Positions.
93    pub fn from_begin_end<Pos>(begin: Pos, end: Pos) -> Self
94    where
95        Pos: Into<Position>,
96    {
97        Self {
98            begin: begin.into(),
99            end: end.into(),
100        }
101    }
102
103    pub fn merge(self, other: Span) -> Span {
104        Span {
105            begin: self.begin,
106            end: other.end,
107        }
108    }
109}
110
111impl Default for Span {
112    fn default() -> Self {
113        Self {
114            begin: Position::new(usize::MIN, usize::MIN),
115            end: Position::new(usize::MAX, usize::MAX),
116        }
117    }
118}
119
120impl Display for Span {
121    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
122        write!(f, "{} - {}", self.begin, self.end)
123    }
124}
125
126pub trait Spanned {
127    fn set_span_begin(&mut self, begin: Position) {
128        self.span_mut().begin = begin;
129    }
130    fn set_span_end(&mut self, end: Position) {
131        self.span_mut().end = end;
132    }
133    fn span(&self) -> &Span;
134    fn span_mut(&mut self) -> &mut Span;
135}