1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
use std::ops::Range;
/// A source code span, used for error reporting.
#[derive(Clone, Copy, Debug, PartialEq, Default)]
pub struct Span {
start: u32,
end: u32,
}
impl Span {
/// Creates a new `Span` from a range of byte indices
///
/// Note: end is exclusive, it doesn't belong to the `Span`
pub fn new(start: u32, end: u32) -> Self {
Span { start, end }
}
/// Modifies `self` to contain the smallest `Span` possible that
/// contains both `self` and `other`
pub fn subsume(&mut self, other: Self) {
*self = if !self.is_defined() {
// self isn't defined so use other
other
} else if !other.is_defined() {
// other isn't defined so don't try to subsume
*self
} else {
// Both self and other are defined so calculate the span that contains them both
Span {
start: self.start.min(other.start),
end: self.end.max(other.end),
}
}
}
/// Returns the smallest `Span` possible that contains all the `Span`s
/// defined in the `from` iterator
pub fn total_span<T: Iterator<Item = Self>>(from: T) -> Self {
let mut span: Self = Default::default();
for other in from {
span.subsume(other);
}
span
}
/// Converts `self` to a range if the span is not unknown
pub fn to_range(self) -> Option<Range<usize>> {
if self.is_defined() {
Some(self.start as usize..self.end as usize)
} else {
None
}
}
/// Check wether `self` was defined or is a default/unknown span
pub fn is_defined(&self) -> bool {
*self != Self::default()
}
}
impl From<Range<usize>> for Span {
fn from(range: Range<usize>) -> Self {
Span {
start: range.start as u32,
end: range.end as u32,
}
}
}