Skip to main content

alopex_sql/ast/
span.rs

1use serde::{Deserialize, Serialize};
2
3/// A location in source text (1-based line/column).
4#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Serialize, Deserialize)]
5pub struct Location {
6    /// Line number (1-based). Zero represents an unknown location.
7    pub line: u64,
8    /// Column number (1-based). Zero represents an unknown location.
9    pub column: u64,
10}
11
12impl Location {
13    /// Returns an unknown/empty location.
14    pub const fn empty() -> Self {
15        Self { line: 0, column: 0 }
16    }
17
18    /// Creates a new location with the given line/column.
19    pub const fn new(line: u64, column: u64) -> Self {
20        Self { line, column }
21    }
22}
23
24/// A span covering a start and end location (inclusive).
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
26pub struct Span {
27    pub start: Location,
28    pub end: Location,
29}
30
31impl Span {
32    /// Returns an unknown/empty span.
33    pub const fn empty() -> Self {
34        Self {
35            start: Location::empty(),
36            end: Location::empty(),
37        }
38    }
39
40    /// Creates a new span from start and end locations.
41    pub const fn new(start: Location, end: Location) -> Self {
42        Self { start, end }
43    }
44
45    /// Returns the minimal span covering both spans.
46    pub fn union(&self, other: &Span) -> Span {
47        if self.start.line == 0 {
48            return *other;
49        }
50        if other.start.line == 0 {
51            return *self;
52        }
53        Span {
54            start: core::cmp::min(self.start, other.start),
55            end: core::cmp::max(self.end, other.end),
56        }
57    }
58}
59
60/// Trait for AST nodes that can report their source span.
61pub trait Spanned {
62    fn span(&self) -> Span;
63}