compiler_tools/
span.rs

1use std::{
2    fmt::{self, Debug, Display},
3    ops::{Deref, DerefMut},
4};
5
6#[derive(Clone, Debug, Copy, Default)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub struct Span {
9    pub line_start: u64,
10    pub line_stop: u64,
11    pub col_start: u64,
12    pub col_stop: u64,
13}
14
15impl PartialEq for Span {
16    fn eq(&self, _other: &Span) -> bool {
17        true
18    }
19}
20
21impl std::hash::Hash for Span {
22    fn hash<H: std::hash::Hasher>(&self, _state: &mut H) {}
23}
24
25impl fmt::Display for Span {
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        if self.line_start == self.line_stop {
28            write!(f, "{}:{}-{}", self.line_start, self.col_start, self.col_stop)
29        } else {
30            write!(f, "{}:{}-{}:{}", self.line_start, self.col_start, self.line_stop, self.col_stop)
31        }
32    }
33}
34
35impl std::ops::Add for Span {
36    type Output = Self;
37
38    fn add(self, other: Self) -> Self {
39        if self.line_start == other.line_stop {
40            Span {
41                line_start: self.line_start,
42                line_stop: self.line_stop,
43                col_start: self.col_start.min(other.col_start),
44                col_stop: self.col_stop.max(other.col_stop),
45            }
46        } else if self.line_start < other.line_start {
47            Span {
48                line_start: self.line_start,
49                line_stop: other.line_stop,
50                col_start: self.col_start,
51                col_stop: other.col_stop,
52            }
53        } else {
54            Span {
55                line_start: other.line_start,
56                line_stop: self.line_stop,
57                col_start: other.col_start,
58                col_stop: self.col_stop,
59            }
60        }
61    }
62}
63
64impl std::ops::AddAssign for Span {
65    fn add_assign(&mut self, rhs: Self) {
66        *self = *self + rhs;
67    }
68}
69
70#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
71#[derive(Clone, Copy)]
72pub struct Spanned<T: Clone + Copy> {
73    pub token: T,
74    pub span: Span,
75}
76
77impl<T: Clone + Copy> Deref for Spanned<T> {
78    type Target = T;
79
80    fn deref(&self) -> &Self::Target {
81        &self.token
82    }
83}
84
85impl<T: Clone + Copy> DerefMut for Spanned<T> {
86    fn deref_mut(&mut self) -> &mut Self::Target {
87        &mut self.token
88    }
89}
90
91impl<T: Clone + Copy + Display> Display for Spanned<T> {
92    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93        write!(f, "'{}' @ {}", self.token, self.span)
94    }
95}
96
97impl<T: Clone + Copy + Debug> Debug for Spanned<T> {
98    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99        write!(f, "'{:?}' @ {}", self.token, self.span)
100    }
101}