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: u32,
9 pub end: u32,
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 pub fn len(&self) -> u32 {
22 self.end - self.start
23 }
24
25 #[must_use]
27 pub fn or(&self, other: Self) -> Self {
28 if self.is_empty() { other } else { *self }
29 }
30
31 #[must_use]
34 pub fn to(&self, other: Self) -> Self {
35 Self {
36 start: self.start.min(other.start),
37 end: self.end.max(other.end),
38 }
39 }
40
41 #[must_use]
43 pub fn skip(&self, skip: Self) -> Self {
44 assert!(skip.end >= self.start);
45 assert!(skip.end <= self.end);
46 Self {
47 start: skip.end,
48 end: self.end,
49 }
50 }
51
52 #[must_use]
54 pub fn start_from(&self, start: Self) -> Self {
55 assert!(start.start >= self.start);
56 assert!(start.start <= self.end);
57 Self {
58 start: start.start,
59 end: self.end,
60 }
61 }
62
63 #[must_use]
65 pub fn collapse_to_end(&self) -> Span {
66 Span {
67 start: self.end,
68 end: self.end,
69 }
70 }
71
72 #[must_use]
74 pub fn collapse_to_start(&self) -> Span {
75 Span {
76 start: self.start,
77 end: self.start,
78 }
79 }
80
81 pub fn overlaps(&self, other: Self) -> bool {
83 self.start < other.end && other.start < self.end
84 }
85
86 pub fn is_selected_at(&self, offset: u32) -> bool {
90 self.start <= offset && offset <= self.end
93 }
94
95 pub fn until_end_of(&self, other: Self) -> Self {
97 Self {
98 start: self.start,
99 end: self.end.min(other.end),
100 }
101 }
102
103 pub fn until_start_of(&self, other: Self) -> Self {
105 Self {
106 start: self.start,
107 end: self.end.min(other.start),
108 }
109 }
110}
111
112impl chumsky::span::Span for Span {
113 type Context = ();
114
115 type Offset = u32;
116
117 fn new(_context: Self::Context, range: Range<Self::Offset>) -> Self {
118 range.into()
119 }
120
121 fn context(&self) -> Self::Context {}
122
123 fn start(&self) -> Self::Offset {
124 self.start
125 }
126
127 fn end(&self) -> Self::Offset {
128 self.end
129 }
130}
131
132impl Display for Span {
133 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134 write!(f, "{}..{}", self.start, self.end)
135 }
136}
137impl Debug for Span {
138 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
139 write!(f, "{}", self)
140 }
141}
142
143impl From<(u32, u32)> for Span {
144 fn from(value: (u32, u32)) -> Self {
145 Self {
146 start: value.0,
147 end: value.1,
148 }
149 }
150}
151
152impl From<Range<u32>> for Span {
153 fn from(value: Range<u32>) -> Self {
154 Self {
155 start: value.start,
156 end: value.end,
157 }
158 }
159}
160
161impl From<Range<usize>> for Span {
162 fn from(value: Range<usize>) -> Self {
163 Self {
164 start: value.start as u32,
165 end: value.end as u32,
166 }
167 }
168}
169
170impl From<Span> for Range<u32> {
171 fn from(value: Span) -> Self {
172 value.start..value.end
173 }
174}
175
176impl From<Span> for Range<usize> {
177 fn from(value: Span) -> Self {
178 value.start as usize..value.end as usize
179 }
180}
181
182impl<'a> From<&'a Span> for Range<u32> {
183 fn from(value: &'a Span) -> Self {
184 value.start..value.end
185 }
186}
187
188impl<'a> From<&'a Span> for Range<usize> {
189 fn from(value: &'a Span) -> Self {
190 value.start as usize..value.end as usize
191 }
192}
193
194#[derive(Clone, Eq, Copy)]
195pub struct Spanned<T> {
196 pub span: Span,
197 pub value: T,
198}
199
200impl<T: PartialEq> PartialEq for Spanned<T> {
201 fn eq(&self, other: &Self) -> bool {
202 self.value == other.value
204 }
205}
206
207impl<T: PartialEq> PartialEq<T> for Spanned<T> {
208 fn eq(&self, other: &T) -> bool {
209 &self.value == other
211 }
212}
213
214impl<T: std::hash::Hash> std::hash::Hash for Spanned<T> {
215 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
216 self.value.hash(state);
217 }
219}
220
221impl<T: Default> Default for Spanned<T> {
222 fn default() -> Self {
223 Self {
224 span: (0, 0).into(),
225 value: Default::default(),
226 }
227 }
228}
229
230impl<T: Display> Display for Spanned<T> {
231 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
232 self.value.fmt(f)
233 }
234}
235
236impl<T: Debug> Debug for Spanned<T> {
237 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
238 self.value.fmt(f)
239 }
240}
241
242impl<T> std::ops::Deref for Spanned<T> {
243 type Target = T;
244
245 fn deref(&self) -> &Self::Target {
246 &self.value
247 }
248}
249
250impl<T> std::ops::DerefMut for Spanned<T> {
251 fn deref_mut(&mut self) -> &mut Self::Target {
252 &mut self.value
253 }
254}
255
256impl<T> Spanned<T> {
257 pub fn new(span: Span, value: T) -> Self {
258 Self { span, value }
259 }
260}
261
262impl<T, S: Into<Span>> From<(T, S)> for Spanned<T> {
263 fn from((value, span): (T, S)) -> Self {
264 Self {
265 span: span.into(),
266 value,
267 }
268 }
269}
270
271impl<T: PartialOrd> PartialOrd<T> for Spanned<T> {
272 fn partial_cmp(&self, other: &T) -> Option<std::cmp::Ordering> {
273 self.value.partial_cmp(other)
274 }
275}
276
277pub trait SpanExt {
278 fn with_span(self, span: impl Into<Span>) -> Spanned<Self>
279 where
280 Self: Sized,
281 {
282 Spanned::new(span.into(), self)
283 }
284
285 fn spanned(self, span: impl Into<Span>) -> Spanned<Self>
287 where
288 Self: Sized,
289 {
290 self.with_span(span)
291 }
292
293 fn with_dummy_span(self) -> Spanned<Self>
294 where
295 Self: Sized,
296 {
297 self.with_span((0, 0))
298 }
299
300 fn into_with_dummy_span<T>(self) -> Spanned<T>
301 where
302 Self: Into<T>,
303 {
304 self.into().with_dummy_span()
305 }
306}
307impl<T> SpanExt for T {}