Skip to main content

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