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}