1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
use miette::SourceSpan;

/// A position or span of text in the source code.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Position {
    /// The starting index of the position, byte-wise. This is inclusive.
    pub start: u32,

    /// The ending index of the position, byte-wise. This is exclusive.
    pub end: u32,
}

impl Position {
    /// Joins two positions together.
    pub fn join(&self, other: &Self) -> Self {
        Self {
            start: self.start.min(other.start),
            end: self.end.max(other.end),
        }
    }
}

/// Creates a position from a start index.
impl From<usize> for Position {
    fn from(start: usize) -> Self {
        Self {
            start: start as u32,
            end: start as u32,
        }
    }
}

/// Creates a position from a start and end index.
impl From<(usize, usize)> for Position {
    fn from((start, end): (usize, usize)) -> Self {
        Self {
            start: start as u32,
            end: end as u32,
        }
    }
}

/// Creates a `miette::SourceSpan` from a `Position`.
impl From<Position> for SourceSpan {
    fn from(val: Position) -> Self {
        SourceSpan::new(
            (val.start as usize).into(),
            ((val.end - val.start) as usize).into(),
        )
    }
}