facet_deserialize/
span.rs

1use core::fmt;
2
3/// Position in the input (byte index)
4pub type Pos = usize;
5
6/// A span in the input, with a start position and length
7#[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
8pub struct Span {
9    /// Starting position of the span in bytes
10    pub start: Pos,
11    /// Length of the span in bytes
12    pub len: usize,
13}
14
15/// Trait for types that can be annotated with a Span.
16pub trait Spannable: Sized {
17    /// Annotate this value with a span, wrapping it in `Spanned<Self>`
18    fn with_span(self, span: Span) -> Spanned<Self>;
19}
20
21impl<T> Spannable for T {
22    fn with_span(self, span: Span) -> Spanned<Self> {
23        Spanned { node: self, span }
24    }
25}
26
27impl Span {
28    /// Creates a new span with the given start position and length
29    pub fn new(start: Pos, len: usize) -> Self {
30        Span { start, len }
31    }
32    /// Start position of the span
33    pub fn start(&self) -> Pos {
34        self.start
35    }
36    /// Length of the span
37    pub fn len(&self) -> usize {
38        self.len
39    }
40    /// Returns `true` if this span has zero length
41    pub fn is_empty(&self) -> bool {
42        self.len == 0
43    }
44    /// End position (start + length)
45    pub fn end(&self) -> Pos {
46        self.start + self.len
47    }
48}
49
50/// A value of type `T` annotated with its `Span`
51#[derive(Debug, Clone, PartialEq, Eq)]
52pub struct Spanned<T> {
53    /// The actual data/value being wrapped
54    pub node: T,
55    /// The span information indicating the position and length in the source
56    pub span: Span,
57}
58
59impl<T: fmt::Display> fmt::Display for Spanned<T> {
60    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61        write!(
62            f,
63            "{} at {}-{}",
64            self.node,
65            self.span.start(),
66            self.span.end()
67        )
68    }
69}