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