Skip to main content

ass_core/parser/ast/
span.rs

1//! Source span tracking for ASS AST nodes
2//!
3//! Provides the zero-copy [`Span`] type recording byte offsets and line/column
4//! position information for nodes referencing the original source text.
5
6/// Represents a span in the source text with position information
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize))]
9pub struct Span {
10    /// Byte offset in source where span starts
11    pub start: usize,
12    /// Byte offset in source where span ends
13    pub end: usize,
14    /// Line number (1-based) where span starts
15    pub line: u32,
16    /// Column number (1-based) where span starts
17    pub column: u32,
18}
19
20impl Span {
21    /// Create a new span with position information
22    #[must_use]
23    pub const fn new(start: usize, end: usize, line: u32, column: u32) -> Self {
24        Self {
25            start,
26            end,
27            line,
28            column,
29        }
30    }
31
32    /// Check if a byte offset is contained within this span
33    #[must_use]
34    pub const fn contains(&self, offset: usize) -> bool {
35        offset >= self.start && offset < self.end
36    }
37
38    /// Merge two spans to create a span covering both
39    #[must_use]
40    pub fn merge(&self, other: &Self) -> Self {
41        use core::cmp::Ordering;
42
43        Self {
44            start: self.start.min(other.start),
45            end: self.end.max(other.end),
46            line: self.line.min(other.line),
47            column: match self.line.cmp(&other.line) {
48                Ordering::Less => self.column,
49                Ordering::Greater => other.column,
50                Ordering::Equal => self.column.min(other.column),
51            },
52        }
53    }
54}