sigil_parser/
span.rs

1//! Source span tracking for error reporting.
2
3use serde::{Deserialize, Serialize};
4use std::fmt;
5
6/// A span in the source code.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
8pub struct Span {
9    pub start: usize,
10    pub end: usize,
11}
12
13impl Span {
14    pub fn new(start: usize, end: usize) -> Self {
15        Self { start, end }
16    }
17
18    pub fn merge(self, other: Span) -> Span {
19        Span {
20            start: self.start.min(other.start),
21            end: self.end.max(other.end),
22        }
23    }
24
25    pub fn len(&self) -> usize {
26        self.end - self.start
27    }
28
29    pub fn is_empty(&self) -> bool {
30        self.start == self.end
31    }
32}
33
34impl fmt::Display for Span {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        write!(f, "{}..{}", self.start, self.end)
37    }
38}
39
40/// A value with an associated span.
41#[derive(Debug, Clone, PartialEq)]
42pub struct Spanned<T> {
43    pub node: T,
44    pub span: Span,
45}
46
47impl<T> Spanned<T> {
48    pub fn new(node: T, span: Span) -> Self {
49        Self { node, span }
50    }
51
52    pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Spanned<U> {
53        Spanned {
54            node: f(self.node),
55            span: self.span,
56        }
57    }
58}