use std::ops::RangeInclusive;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct Span(u32, u32);
impl Span {
pub const NONE: Span = Span(u32::MAX, u32::MAX);
#[inline]
pub fn new(start: usize, end: usize) -> Self {
Span(start as u32, end as u32)
}
#[inline]
pub fn from_range(range: RangeInclusive<usize>) -> Self {
Span(*range.start() as u32, *range.end() as u32)
}
#[inline]
pub fn is_none(&self) -> bool {
self.0 == u32::MAX && self.1 == u32::MAX
}
#[inline]
pub fn to_range(&self) -> Option<RangeInclusive<usize>> {
if self.is_none() {
None
} else {
Some(self.0 as usize..=self.1 as usize)
}
}
#[inline]
pub fn start(&self) -> Option<usize> {
if self.is_none() {
None
} else {
Some(self.0 as usize)
}
}
#[inline]
pub fn end(&self) -> Option<usize> {
if self.is_none() {
None
} else {
Some(self.1 as usize)
}
}
}
impl From<RangeInclusive<usize>> for Span {
fn from(range: RangeInclusive<usize>) -> Self {
Span::from_range(range)
}
}
impl From<Option<RangeInclusive<usize>>> for Span {
fn from(opt: Option<RangeInclusive<usize>>) -> Self {
match opt {
Some(range) => Span::from_range(range),
None => Span::NONE,
}
}
}
pub trait Spannable {
fn span(&self) -> Option<RangeInclusive<usize>>;
}
impl Spannable for Span {
fn span(&self) -> Option<RangeInclusive<usize>> {
self.to_range()
}
}
impl<'a, T: antlr_rust::parser_rule_context::ParserRuleContext<'a>> Spannable for T {
fn span(&self) -> Option<RangeInclusive<usize>> {
Some(crate::antlr::interval(self))
}
}