device_driver_common/
span.rs1use std::{
2 fmt::{Debug, Display},
3 ops::Range,
4};
5
6#[derive(Clone, Eq, PartialEq, Copy, Default, Hash)]
7pub struct Span {
8 pub start: usize,
9 pub end: usize,
10}
11
12impl Span {
13 pub const fn empty() -> Self {
14 Self { start: 0, end: 0 }
15 }
16
17 pub fn is_empty(&self) -> bool {
18 self.start == 0 && self.end == 0
19 }
20
21 #[must_use]
23 pub fn or(&self, other: Self) -> Self {
24 if self.is_empty() { other } else { *self }
25 }
26
27 #[must_use]
30 pub fn to(&self, other: Self) -> Self {
31 Self {
32 start: self.start.min(other.start),
33 end: self.end.max(other.end),
34 }
35 }
36
37 #[must_use]
39 pub fn skip(&self, skip: Self) -> Self {
40 assert!(skip.end >= self.start);
41 assert!(skip.end <= self.end);
42 Self {
43 start: skip.end,
44 end: self.end,
45 }
46 }
47
48 #[must_use]
50 pub fn start_from(&self, start: Self) -> Self {
51 assert!(start.start >= self.start);
52 assert!(start.start <= self.end);
53 Self {
54 start: start.start,
55 end: self.end,
56 }
57 }
58
59 #[must_use]
61 pub fn collapse_to_end(&self) -> Span {
62 Span {
63 start: self.end,
64 end: self.end,
65 }
66 }
67}
68
69impl chumsky::span::Span for Span {
70 type Context = ();
71
72 type Offset = usize;
73
74 fn new(_context: Self::Context, range: Range<Self::Offset>) -> Self {
75 range.into()
76 }
77
78 fn context(&self) -> Self::Context {}
79
80 fn start(&self) -> Self::Offset {
81 self.start
82 }
83
84 fn end(&self) -> Self::Offset {
85 self.end
86 }
87}
88
89impl Display for Span {
90 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91 write!(f, "{}..{}", self.start, self.end)
92 }
93}
94impl Debug for Span {
95 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96 write!(f, "{}", self)
97 }
98}
99
100impl From<(usize, usize)> for Span {
101 fn from(value: (usize, usize)) -> Self {
102 Self {
103 start: value.0,
104 end: value.1,
105 }
106 }
107}
108
109impl From<Range<usize>> for Span {
110 fn from(value: Range<usize>) -> Self {
111 Self {
112 start: value.start,
113 end: value.end,
114 }
115 }
116}
117
118impl From<Span> for Range<usize> {
119 fn from(value: Span) -> Self {
120 value.start..value.end
121 }
122}
123
124impl<'a> From<&'a Span> for Range<usize> {
125 fn from(value: &'a Span) -> Self {
126 value.start..value.end
127 }
128}
129
130#[derive(Clone, Eq, Copy)]
131pub struct Spanned<T> {
132 pub span: Span,
133 pub value: T,
134}
135
136impl<T: PartialEq> PartialEq for Spanned<T> {
137 fn eq(&self, other: &Self) -> bool {
138 self.value == other.value
140 }
141}
142
143impl<T: PartialEq> PartialEq<T> for Spanned<T> {
144 fn eq(&self, other: &T) -> bool {
145 &self.value == other
147 }
148}
149
150impl<T: std::hash::Hash> std::hash::Hash for Spanned<T> {
151 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
152 self.value.hash(state);
153 }
155}
156
157impl<T: Default> Default for Spanned<T> {
158 fn default() -> Self {
159 Self {
160 span: (0, 0).into(),
161 value: Default::default(),
162 }
163 }
164}
165
166impl<T: Display> Display for Spanned<T> {
167 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
168 self.value.fmt(f)
169 }
170}
171
172impl<T: Debug> Debug for Spanned<T> {
173 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
174 self.value.fmt(f)
175 }
176}
177
178impl<T> std::ops::Deref for Spanned<T> {
179 type Target = T;
180
181 fn deref(&self) -> &Self::Target {
182 &self.value
183 }
184}
185
186impl<T> std::ops::DerefMut for Spanned<T> {
187 fn deref_mut(&mut self) -> &mut Self::Target {
188 &mut self.value
189 }
190}
191
192impl<T> Spanned<T> {
193 pub fn new(span: Span, value: T) -> Self {
194 Self { span, value }
195 }
196}
197
198impl<T, S: Into<Span>> From<(T, S)> for Spanned<T> {
199 fn from((value, span): (T, S)) -> Self {
200 Self {
201 span: span.into(),
202 value,
203 }
204 }
205}
206
207impl<T: PartialOrd> PartialOrd<T> for Spanned<T> {
208 fn partial_cmp(&self, other: &T) -> Option<std::cmp::Ordering> {
209 self.value.partial_cmp(other)
210 }
211}
212
213pub trait SpanExt {
214 fn with_span(self, span: impl Into<Span>) -> Spanned<Self>
215 where
216 Self: Sized,
217 {
218 Spanned::new(span.into(), self)
219 }
220
221 fn spanned(self, span: impl Into<Span>) -> Spanned<Self>
223 where
224 Self: Sized,
225 {
226 self.with_span(span)
227 }
228
229 fn with_dummy_span(self) -> Spanned<Self>
230 where
231 Self: Sized,
232 {
233 self.with_span((0, 0))
234 }
235
236 fn into_with_dummy_span<T>(self) -> Spanned<T>
237 where
238 Self: Into<T>,
239 {
240 self.into().with_dummy_span()
241 }
242}
243impl<T> SpanExt for T {}