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}