1#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
2pub struct Span {
3 pub start: usize,
4 pub end: usize,
5}
6
7impl Span {
8 pub fn new(start: usize, end: usize) -> Self {
9 Self { start, end }
10 }
11
12 pub fn overlaps(&self, other: Span) -> bool {
16 self.start < other.end && other.start < self.end
17 }
18}
19
20#[cfg(test)]
21mod tests {
22 use super::*;
23
24 #[track_caller]
25 fn assert_overlap(a: Span, b: Span) {
26 let forward = a.overlaps(b);
27 let back = b.overlaps(a);
28 assert_eq!(forward, back);
29
30 assert!(
31 forward,
32 "Expected {a:?} and {b:?} to overlap but they don't."
33 );
34 }
35
36 #[track_caller]
37 fn assert_no_overlap(a: Span, b: Span) {
38 let forward = a.overlaps(b);
39 let back = b.overlaps(a);
40 assert_eq!(forward, back);
41
42 assert!(
43 !forward,
44 "Expected {a:?} and {b:?} not to overlap but they do."
45 );
46 }
47
48 #[test]
49 fn empty_spans_never_overlap() {
50 assert_no_overlap(Span { start: 0, end: 0 }, Span { start: 0, end: 0 });
51 assert_no_overlap(Span { start: 0, end: 0 }, Span { start: 10, end: 10 });
52 assert_no_overlap(Span { start: 100, end: 0 }, Span { start: 10, end: 10 });
53 }
54
55 #[test]
56 fn overlap_tests() {
57 assert_overlap(Span { start: 0, end: 10 }, Span { start: 5, end: 15 });
58 assert_overlap(Span { start: 5, end: 15 }, Span { start: 0, end: 10 });
59 assert_overlap(Span { start: 0, end: 10 }, Span { start: 0, end: 10 });
60 assert_overlap(Span { start: 0, end: 10 }, Span { start: 0, end: 5 });
61 assert_overlap(Span { start: 0, end: 10 }, Span { start: 5, end: 10 });
62
63 assert_no_overlap(Span { start: 10, end: 20 }, Span { start: 20, end: 30 });
64 assert_no_overlap(Span { start: 10, end: 20 }, Span { start: 30, end: 40 });
65 }
66}