Skip to main content

meta_language/
source.rs

1/// Half-open byte range in source text.
2#[derive(Clone, Copy, Debug, PartialEq, Eq)]
3pub struct ByteRange {
4    start: usize,
5    end: usize,
6}
7
8impl ByteRange {
9    /// Creates a byte range.
10    ///
11    /// # Panics
12    ///
13    /// Panics when `start` is greater than `end`.
14    #[must_use]
15    pub const fn new(start: usize, end: usize) -> Self {
16        assert!(start <= end, "byte range start must not exceed end");
17        Self { start, end }
18    }
19
20    /// First byte in the range.
21    #[must_use]
22    pub const fn start(self) -> usize {
23        self.start
24    }
25
26    /// Byte immediately after the range.
27    #[must_use]
28    pub const fn end(self) -> usize {
29        self.end
30    }
31
32    /// Returns `true` when this range intersects `other`.
33    #[must_use]
34    pub const fn intersects(self, other: Self) -> bool {
35        if self.start == self.end || other.start == other.end {
36            self.start <= other.end && other.start <= self.end
37        } else {
38            self.start < other.end && other.start < self.end
39        }
40    }
41}
42
43/// Row and column point in source text.
44#[derive(Clone, Copy, Debug, PartialEq, Eq)]
45pub struct Point {
46    row: usize,
47    column: usize,
48}
49
50impl Point {
51    /// Creates a row/column point.
52    #[must_use]
53    pub const fn new(row: usize, column: usize) -> Self {
54        Self { row, column }
55    }
56
57    /// Zero-based row.
58    #[must_use]
59    pub const fn row(self) -> usize {
60        self.row
61    }
62
63    /// Zero-based column.
64    #[must_use]
65    pub const fn column(self) -> usize {
66        self.column
67    }
68}
69
70/// Source span attached to a link.
71#[derive(Clone, Copy, Debug, PartialEq, Eq)]
72pub struct SourceSpan {
73    byte_range: ByteRange,
74    start_point: Point,
75    end_point: Point,
76}
77
78impl SourceSpan {
79    /// Creates a source span from byte and point ranges.
80    #[must_use]
81    pub const fn new(byte_range: ByteRange, start_point: Point, end_point: Point) -> Self {
82        Self {
83            byte_range,
84            start_point,
85            end_point,
86        }
87    }
88
89    /// Byte range covered by the span.
90    #[must_use]
91    pub const fn byte_range(self) -> ByteRange {
92        self.byte_range
93    }
94
95    /// Start row/column point.
96    #[must_use]
97    pub const fn start_point(self) -> Point {
98        self.start_point
99    }
100
101    /// End row/column point.
102    #[must_use]
103    pub const fn end_point(self) -> Point {
104        self.end_point
105    }
106}