Skip to main content

php_ast/
span.rs

1use serde::Serialize;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)]
4pub struct Span {
5    pub start: u32,
6    pub end: u32,
7}
8
9impl Span {
10    pub const DUMMY: Span = Span { start: 0, end: 0 };
11
12    pub fn new(start: u32, end: u32) -> Self {
13        Self { start, end }
14    }
15
16    pub fn merge(self, other: Span) -> Span {
17        Span {
18            start: self.start.min(other.start),
19            end: self.end.max(other.end),
20        }
21    }
22
23    pub fn len(self) -> u32 {
24        self.end - self.start
25    }
26
27    pub fn is_empty(self) -> bool {
28        self.start == self.end
29    }
30}
31
32impl Default for Span {
33    fn default() -> Self {
34        Self::DUMMY
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41
42    #[test]
43    fn test_span_new() {
44        let span = Span::new(5, 10);
45        assert_eq!(span.start, 5);
46        assert_eq!(span.end, 10);
47    }
48
49    #[test]
50    fn test_span_merge() {
51        let a = Span::new(5, 10);
52        let b = Span::new(8, 15);
53        let merged = a.merge(b);
54        assert_eq!(merged.start, 5);
55        assert_eq!(merged.end, 15);
56    }
57
58    #[test]
59    fn test_span_merge_non_overlapping() {
60        let a = Span::new(0, 5);
61        let b = Span::new(10, 20);
62        let merged = a.merge(b);
63        assert_eq!(merged.start, 0);
64        assert_eq!(merged.end, 20);
65    }
66
67    #[test]
68    fn test_span_len() {
69        let span = Span::new(3, 10);
70        assert_eq!(span.len(), 7);
71    }
72
73    #[test]
74    fn test_span_is_empty() {
75        assert!(Span::new(5, 5).is_empty());
76        assert!(!Span::new(5, 6).is_empty());
77    }
78
79    #[test]
80    fn test_span_dummy() {
81        assert_eq!(Span::DUMMY, Span::new(0, 0));
82        assert!(Span::DUMMY.is_empty());
83    }
84
85    #[test]
86    fn test_span_default() {
87        assert_eq!(Span::default(), Span::DUMMY);
88    }
89}