1use std::ops::Range;
2
3#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
5pub struct Span(Range<usize>);
6
7impl Span {
8 pub const fn new(start: usize, end: usize) -> Self {
10 Self(start..end)
11 }
12
13 pub const fn start(&self) -> usize {
15 self.0.start
16 }
17
18 pub const fn end(&self) -> usize {
20 self.0.end
21 }
22
23 pub fn as_range(&self) -> Range<usize> {
25 self.0.clone()
26 }
27
28 pub fn len(&self) -> usize {
30 self.0.len()
31 }
32
33 pub fn is_empty(&self) -> bool {
35 self.0.is_empty()
36 }
37}
38
39impl From<Range<usize>> for Span {
40 fn from(value: Range<usize>) -> Self {
41 Self(value)
42 }
43}
44
45impl From<Span> for Range<usize> {
46 fn from(value: Span) -> Self {
47 value.0
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use super::Span;
54
55 #[test]
56 fn span_exposes_offsets_and_length() {
57 let span = Span::new(2, 5);
58
59 assert_eq!(span.start(), 2);
60 assert_eq!(span.end(), 5);
61 assert_eq!(span.len(), 3);
62 assert!(!span.is_empty());
63 assert_eq!(span.as_range(), 2..5);
64 }
65
66 #[test]
67 fn empty_span_reports_empty() {
68 let span = Span::new(3, 3);
69
70 assert!(span.is_empty());
71 assert_eq!(span.len(), 0);
72 }
73}