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(Debug, 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> std::ops::Deref for Spanned<T> {
173 type Target = T;
174
175 fn deref(&self) -> &Self::Target {
176 &self.value
177 }
178}
179
180impl<T> std::ops::DerefMut for Spanned<T> {
181 fn deref_mut(&mut self) -> &mut Self::Target {
182 &mut self.value
183 }
184}
185
186impl<T> Spanned<T> {
187 pub fn new(span: Span, value: T) -> Self {
188 Self { span, value }
189 }
190}
191
192impl<T, S: Into<Span>> From<(T, S)> for Spanned<T> {
193 fn from((value, span): (T, S)) -> Self {
194 Self {
195 span: span.into(),
196 value,
197 }
198 }
199}
200
201impl<T: PartialOrd> PartialOrd<T> for Spanned<T> {
202 fn partial_cmp(&self, other: &T) -> Option<std::cmp::Ordering> {
203 self.value.partial_cmp(other)
204 }
205}
206
207pub trait SpanExt {
208 fn with_span(self, span: impl Into<Span>) -> Spanned<Self>
209 where
210 Self: Sized,
211 {
212 Spanned::new(span.into(), self)
213 }
214
215 fn spanned(self, span: impl Into<Span>) -> Spanned<Self>
217 where
218 Self: Sized,
219 {
220 self.with_span(span)
221 }
222
223 fn with_dummy_span(self) -> Spanned<Self>
224 where
225 Self: Sized,
226 {
227 self.with_span((0, 0))
228 }
229
230 fn into_with_dummy_span<T>(self) -> Spanned<T>
231 where
232 Self: Into<T>,
233 {
234 self.into().with_dummy_span()
235 }
236}
237impl<T> SpanExt for T {}