Skip to main content

shape_ast/ast/
span.rs

1//! Source span tracking for AST nodes
2
3use serde::{Deserialize, Serialize};
4
5/// Lightweight source span for AST nodes.
6/// Stores byte offsets from the beginning of the source text.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
8pub struct Span {
9    /// Start position (byte offset)
10    pub start: usize,
11    /// End position (byte offset)
12    pub end: usize,
13}
14
15impl Span {
16    /// A dummy span for AST nodes without source location
17    pub const DUMMY: Span = Span { start: 0, end: 0 };
18
19    /// Create a new span from start and end byte offsets
20    pub fn new(start: usize, end: usize) -> Self {
21        Self { start, end }
22    }
23
24    /// Merge two spans to create a span covering both
25    pub fn merge(self, other: Span) -> Span {
26        Span {
27            start: self.start.min(other.start),
28            end: self.end.max(other.end),
29        }
30    }
31
32    /// Get the length of the span in bytes
33    pub fn len(&self) -> usize {
34        self.end.saturating_sub(self.start)
35    }
36
37    /// Check if the span is empty
38    pub fn is_empty(&self) -> bool {
39        self.start >= self.end
40    }
41
42    /// Check if this is a dummy span
43    pub fn is_dummy(&self) -> bool {
44        self.start == 0 && self.end == 0
45    }
46}
47
48/// Trait for AST nodes that have source location information
49pub trait Spanned {
50    /// Get the source span for this node
51    fn span(&self) -> Span;
52}