///|
/// A half-open byte range in a source file.
pub struct Span {
start : Int
end : Int
} derive(Eq, Debug)
///|
/// Creates a span when both offsets are non-negative and ordered.
pub fn Span::new(start : Int, end : Int) -> Span? {
if start < 0 || end < start {
None
} else {
Some({ start, end })
}
}
///|
pub fn Span::at(offset : Int) -> Span? {
Span::new(offset, offset)
}
///|
pub fn Span::start(self : Span) -> Int {
self.start
}
///|
pub fn Span::end(self : Span) -> Int {
self.end
}
///|
pub fn Span::length(self : Span) -> Int {
self.end - self.start
}
///|
pub fn Span::is_empty(self : Span) -> Bool {
self.start == self.end
}
///|
pub fn Span::contains(self : Span, offset : Int) -> Bool {
self.start <= offset && offset < self.end
}
///|
pub fn Span::touches(self : Span, other : Span) -> Bool {
self.start <= other.end && other.start <= self.end
}
///|
pub fn Span::intersects(self : Span, other : Span) -> Bool {
self.start < other.end && other.start < self.end
}
///|
pub fn Span::cover(self : Span, other : Span) -> Span {
{
start: if self.start < other.start {
self.start
} else {
other.start
},
end: if self.end > other.end {
self.end
} else {
other.end
},
}
}
///|
pub fn Span::clamp(self : Span, length : Int) -> Span {
let upper = if length < 0 { 0 } else { length }
let start = if self.start > upper { upper } else { self.start }
let end = if self.end > upper { upper } else { self.end }
{ start, end: if end < start { start } else { end } }
}