use std::ops::{Index, IndexMut, Range};
#[derive(Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub struct Span {
pub start: usize,
pub end: usize,
}
impl Span {
#[inline(always)]
pub fn new(start: usize, end: usize) -> Self {
Self {
start,
end: std::cmp::max(start, end),
}
}
#[inline(always)]
pub fn len(&self) -> usize {
if self.start > self.end {
0
} else {
self.end - self.start
}
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.end == self.start
}
#[inline(always)]
pub fn range(&self) -> Range<usize> {
self.start..self.end
}
#[inline(always)]
pub fn contains(&self, index: usize) -> bool {
self.start >= index && index < self.end
}
#[inline(always)]
pub fn union(&self, other: Self) -> Self {
Self {
start: std::cmp::min(self.start, other.start),
end: std::cmp::max(self.end, other.end),
}
}
#[inline(always)]
pub fn append(&mut self, other: Self) {
self.start = std::cmp::min(self.start, other.start);
self.end = std::cmp::max(self.end, other.end)
}
#[inline(always)]
pub fn inter(&self, other: Self) -> Self {
let start = std::cmp::max(self.start, other.start);
Self {
start,
end: std::cmp::max(start, std::cmp::min(self.end, other.end)),
}
}
#[inline(always)]
pub fn clear(&mut self) {
self.start = self.end
}
#[inline(always)]
pub fn next(&self) -> Self {
self.end.into()
}
#[inline(always)]
pub fn push(&mut self, count: usize) {
self.end += count
}
}
impl From<usize> for Span {
fn from(pos: usize) -> Self {
Self::new(pos, pos)
}
}
impl From<Range<usize>> for Span {
fn from(range: Range<usize>) -> Self {
Self::new(range.start, range.end)
}
}
impl From<Span> for Range<usize> {
fn from(span: Span) -> Self {
Self {
start: span.start,
end: span.end,
}
}
}
impl IntoIterator for Span {
type Item = usize;
type IntoIter = Range<usize>;
fn into_iter(self) -> Self::IntoIter {
self.range()
}
}
impl IntoIterator for &Span {
type Item = usize;
type IntoIter = Range<usize>;
fn into_iter(self) -> Self::IntoIter {
self.range()
}
}
impl Index<Span> for str {
type Output = str;
fn index(&self, span: Span) -> &str {
self.index(span.range())
}
}
impl IndexMut<Span> for str {
fn index_mut(&mut self, span: Span) -> &mut str {
self.index_mut(span.range())
}
}
impl Index<Span> for String {
type Output = str;
fn index(&self, span: Span) -> &str {
self.index(span.range())
}
}
impl IndexMut<Span> for String {
fn index_mut(&mut self, span: Span) -> &mut str {
self.index_mut(span.range())
}
}
pub trait Spanned {
fn span(&self) -> Span;
}
impl Spanned for Span {
fn span(&self) -> Span {
*self
}
}
pub trait MaybeSpanned {
fn optional_span(&self) -> Option<Span>;
}
impl MaybeSpanned for Span {
fn optional_span(&self) -> Option<Span> {
Some(*self)
}
}