use std::ops::{Index, IndexMut, Range};
#[derive(Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub struct Span {
start: usize,
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 {
self.end - self.start
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.end == self.start
}
#[inline(always)]
pub fn start(&self) -> usize {
self.start
}
#[inline(always)]
pub fn end(&self) -> usize {
self.end
}
#[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 set_start(&mut self, start: usize) {
self.start = start;
self.end = std::cmp::max(start, self.end);
}
#[inline(always)]
pub fn set_end(&mut self, end: usize) {
self.end = std::cmp::max(self.start, 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<'a> IntoIterator for &'a 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 {
type Span;
fn span(&self) -> Self::Span;
}
impl Spanned for Span {
type Span = Self;
fn span(&self) -> Self::Span {
*self
}
}
pub trait MaybeSpanned {
type Span;
fn optional_span(&self) -> Option<Self::Span>;
}
impl MaybeSpanned for Span {
type Span = Self;
fn optional_span(&self) -> Option<Self::Span> {
Some(*self)
}
}
pub trait SpannedMut: Spanned {
fn span_mut(&mut self) -> &mut Self::Span;
}
impl SpannedMut for Span {
fn span_mut(&mut self) -> &mut Self::Span {
self
}
}
pub trait MaybeSpannedMut: MaybeSpanned {
fn optional_span_mut(&mut self) -> Option<&mut Self::Span>;
}
impl MaybeSpannedMut for Span {
fn optional_span_mut(&mut self) -> Option<&mut Self::Span> {
Some(self)
}
}