use std::{fmt, ops::Range};
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Span {
pub start: usize,
pub end: usize,
}
impl From<(usize, usize)> for Span {
fn from((start, end): (usize, usize)) -> Self {
Self { start, end }
}
}
impl From<Range<usize>> for Span {
fn from(r: Range<usize>) -> Self {
Self {
start: r.start,
end: r.end,
}
}
}
impl From<Span> for Range<usize> {
fn from(s: Span) -> Self {
s.start..s.end
}
}
impl Span {
#[must_use]
pub const fn new(start: usize, end: usize) -> Self {
Self { start, end }
}
#[must_use]
pub const fn empty(at: usize) -> Self {
Self { start: at, end: at }
}
#[must_use]
pub const fn len(self) -> usize {
self.end.saturating_sub(self.start)
}
#[must_use]
pub const fn is_empty(self) -> bool {
self.start >= self.end
}
#[must_use]
pub const fn contains(self, pos: usize) -> bool {
self.start <= pos && pos < self.end
}
}
impl fmt::Debug for Span {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}..{}", self.start, self.end)
}
}
#[must_use]
pub const fn span(start: usize, end: usize) -> Span {
Span::new(start, end)
}