jsonpath_plus/ast/
span.rs1use core::ops;
2use std::fmt;
3
4#[cfg_attr(docsrs, doc(cfg(feature = "spanned")))]
7#[derive(Copy, Clone, PartialEq)]
8pub struct Span {
9 start: usize,
10 end: usize,
11}
12
13impl Span {
14 pub(crate) fn join(self, other: Span) -> Span {
15 let start = usize::min(self.start, other.start);
16 let end = usize::max(self.end, other.end);
17 Span { start, end }
18 }
19
20 pub(crate) fn start(&self) -> usize {
21 self.start
22 }
23
24 pub(crate) fn end(&self) -> usize {
25 self.end
26 }
27
28 #[must_use]
31 pub fn get_span(self, source: &str) -> &str {
32 let start = source.char_indices().nth(self.start);
33
34 let end = source.char_indices().nth(self.end);
35
36 let ((start, _), (end, _)) = start.zip(end).expect("Invalid source for span");
37
38 &source[start..end]
39 }
40}
41
42impl From<ops::Range<usize>> for Span {
43 fn from(span: ops::Range<usize>) -> Self {
44 Span {
45 start: span.start,
46 end: span.end,
47 }
48 }
49}
50
51impl fmt::Debug for Span {
52 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53 f.debug_tuple("Span")
54 .field(&(self.start..self.end))
55 .finish()
56 }
57}
58
59impl chumsky::Span for Span {
60 type Context = ();
61 type Offset = usize;
62
63 fn new(_context: Self::Context, range: ops::Range<Self::Offset>) -> Self {
64 range.into()
65 }
66
67 fn context(&self) -> Self::Context {}
68
69 fn start(&self) -> Self::Offset {
70 self.start
71 }
72
73 fn end(&self) -> Self::Offset {
74 self.end
75 }
76}
77
78#[cfg(feature = "spanned")]
80#[cfg_attr(docsrs, doc(cfg(feature = "spanned")))]
81pub trait Spanned {
82 fn span(&self) -> Span;
84}
85
86#[cfg(feature = "spanned")]
87mod __impl {
88 use super::*;
89 use crate::ast::*;
90
91 impl Spanned for Ident {
94 fn span(&self) -> Span {
95 self.span
96 }
97 }
98
99 impl Spanned for BoolLit {
100 fn span(&self) -> Span {
101 self.span
102 }
103 }
104
105 impl Spanned for NullLit {
106 fn span(&self) -> Span {
107 self.span
108 }
109 }
110
111 impl Spanned for IntLit {
112 fn span(&self) -> Span {
113 self.span
114 }
115 }
116
117 impl Spanned for NonZeroIntLit {
118 fn span(&self) -> Span {
119 self.span
120 }
121 }
122
123 impl Spanned for StringContent {
124 fn span(&self) -> Span {
125 self.span
126 }
127 }
128
129 impl Spanned for SingleStringLit {
130 fn span(&self) -> Span {
131 self.start
132 .span()
133 .join(self.content.span())
134 .join(self.end.span())
135 }
136 }
137
138 impl Spanned for DoubleStringLit {
139 fn span(&self) -> Span {
140 self.start
141 .span()
142 .join(self.content.span())
143 .join(self.end.span())
144 }
145 }
146
147 impl Spanned for StringLit {
148 fn span(&self) -> Span {
149 match self {
150 StringLit::Single(s) => s.span(),
151 StringLit::Double(d) => d.span(),
152 }
153 }
154 }
155
156 impl Spanned for Path {
159 fn span(&self) -> Span {
160 let mut out = self.dollar.span();
161
162 for s in &self.segments {
163 out = out.join(s.span());
164 }
165
166 if let Some(t) = &self.tilde {
167 out = out.join(t.span());
168 }
169
170 out
171 }
172 }
173
174 impl Spanned for SubPath {
175 fn span(&self) -> Span {
176 let mut out = self.kind.span();
177
178 for s in &self.segments {
179 out = out.join(s.span());
180 }
181
182 if let Some(t) = &self.tilde {
183 out = out.join(t.span());
184 }
185
186 out
187 }
188 }
189
190 impl Spanned for PathKind {
191 fn span(&self) -> Span {
192 match self {
193 PathKind::Root(d) => d.span(),
194 PathKind::Relative(a) => a.span(),
195 }
196 }
197 }
198
199 impl Spanned for Segment {
200 fn span(&self) -> Span {
201 match self {
202 Segment::Bracket(b, i) => b.span().join(i.span()),
203 Segment::Dot(d, i) => d.span().join(i.span()),
204 Segment::Recursive(r, i) => i
205 .as_ref()
206 .map_or_else(|| r.span(), |i| r.span().join(i.span())),
207 }
208 }
209 }
210
211 impl Spanned for BracketSelector {
212 fn span(&self) -> Span {
213 match self {
214 BracketSelector::Union(comps) => {
215 let mut out = comps[0].span();
216 for comp in &comps[1..] {
217 out = out.join(comp.span());
218 }
219 out
220 }
221 BracketSelector::StepRange(sr) => sr.span(),
222 BracketSelector::Range(r) => r.span(),
223 BracketSelector::Wildcard(s) => s.span(),
224 BracketSelector::Parent(c) => c.span(),
225 BracketSelector::Path(sp) => sp.span(),
226 BracketSelector::Filter(f) => f.span(),
227 BracketSelector::Literal(lit) => lit.span(),
228 }
229 }
230 }
231
232 impl Spanned for RawSelector {
233 fn span(&self) -> Span {
234 match self {
235 RawSelector::Wildcard(s) => s.span(),
236 RawSelector::Parent(c) => c.span(),
237 RawSelector::Name(i) => i.span(),
238 }
239 }
240 }
241
242 impl Spanned for UnionComponent {
243 fn span(&self) -> Span {
244 match self {
245 UnionComponent::StepRange(sr) => sr.span(),
246 UnionComponent::Range(r) => r.span(),
247 UnionComponent::Parent(c) => c.span(),
248 UnionComponent::Path(sp) => sp.span(),
249 UnionComponent::Filter(f) => f.span(),
250 UnionComponent::Literal(lit) => lit.span(),
251 }
252 }
253 }
254
255 impl Spanned for StepRange {
256 fn span(&self) -> Span {
257 let mut out = self
258 .start
259 .as_ref()
260 .map_or_else(|| self.colon1.span(), |s| s.span().join(self.colon1.span()));
261
262 if let Some(end) = &self.end {
263 out = out.join(end.span());
264 }
265
266 out = out.join(self.colon2.span());
267
268 if let Some(step) = &self.step {
269 out = out.join(step.span());
270 }
271
272 out
273 }
274 }
275
276 impl Spanned for Range {
277 fn span(&self) -> Span {
278 let mut out = self
279 .start
280 .as_ref()
281 .map_or_else(|| self.colon.span(), |s| s.span().join(self.colon.span()));
282
283 if let Some(end) = &self.end {
284 out = out.join(end.span());
285 }
286
287 out
288 }
289 }
290
291 impl Spanned for BracketLit {
292 fn span(&self) -> Span {
293 match self {
294 BracketLit::Int(i) => i.span(),
295 BracketLit::String(s) => s.span(),
296 }
297 }
298 }
299
300 impl Spanned for Filter {
301 fn span(&self) -> Span {
302 self.question
303 .span()
304 .join(self.paren.span())
305 .join(self.inner.span())
306 }
307 }
308
309 impl Spanned for FilterExpr {
310 fn span(&self) -> Span {
311 match self {
312 FilterExpr::Unary(op, expr) => op.span().join(expr.span()),
313 FilterExpr::Binary(lhs, op, rhs) => lhs.span().join(op.span()).join(rhs.span()),
314 FilterExpr::Path(sp) => sp.span(),
315 FilterExpr::Lit(el) => el.span(),
316 FilterExpr::Parens(p, expr) => p.span().join(expr.span()),
317 }
318 }
319 }
320
321 impl Spanned for ExprLit {
322 fn span(&self) -> Span {
323 match self {
324 ExprLit::Int(i) => i.span(),
325 ExprLit::String(s) => s.span(),
326 ExprLit::Bool(b) => b.span(),
327 ExprLit::Null(n) => n.span(),
328 }
329 }
330 }
331
332 impl Spanned for UnOp {
333 fn span(&self) -> Span {
334 match self {
335 UnOp::Neg(d) => d.span(),
336 UnOp::Not(b) => b.span(),
337 }
338 }
339 }
340
341 impl Spanned for BinOp {
342 fn span(&self) -> Span {
343 match self {
344 BinOp::And(a) => a.span(),
345 BinOp::Or(p) => p.span(),
346 BinOp::Eq(e) => e.span(),
347 BinOp::Le(l) => l.span(),
348 BinOp::Lt(l) => l.span(),
349 BinOp::Gt(g) => g.span(),
350 BinOp::Ge(g) => g.span(),
351 BinOp::Add(p) => p.span(),
352 BinOp::Sub(d) => d.span(),
353 BinOp::Mul(s) => s.span(),
354 BinOp::Div(s) => s.span(),
355 BinOp::Rem(p) => p.span(),
356 }
357 }
358 }
359}