use super::*;
pub trait Span {
type Context;
type Offset: Clone;
fn new(context: Self::Context, range: Range<Self::Offset>) -> Self;
fn context(&self) -> Self::Context;
fn start(&self) -> Self::Offset;
fn end(&self) -> Self::Offset;
fn to_end(&self) -> Self
where
Self: Sized,
{
Self::new(self.context(), self.end()..self.end())
}
fn union(&self, other: Self) -> Self
where
Self::Context: PartialEq + fmt::Debug,
Self::Offset: Ord,
Self: Sized,
{
assert_eq!(
self.context(),
other.context(),
"tried to union two spans with different contexts"
);
Self::new(
self.context(),
self.start().min(other.start())..self.end().max(other.end()),
)
}
}
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SimpleSpan<T = usize, C = ()> {
pub start: T,
pub end: T,
pub context: C,
}
impl<T, C> SimpleSpan<T, C> {
pub fn into_range(self) -> Range<T> {
self.start..self.end
}
}
impl<T> From<Range<T>> for SimpleSpan<T> {
fn from(range: Range<T>) -> Self {
SimpleSpan {
start: range.start,
end: range.end,
context: (),
}
}
}
impl<T> From<SimpleSpan<T, ()>> for Range<T> {
fn from(span: SimpleSpan<T>) -> Self {
Range {
start: span.start,
end: span.end,
}
}
}
impl<T, C> fmt::Debug for SimpleSpan<T, C>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}..{:?}", self.start, self.end)
}
}
impl<T, C> fmt::Display for SimpleSpan<T, C>
where
T: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}..{}", self.start, self.end)
}
}
impl<T, C> IntoIterator for SimpleSpan<T, C>
where
Range<T>: Iterator<Item = T>,
{
type IntoIter = Range<T>;
type Item = T;
fn into_iter(self) -> Self::IntoIter {
self.start..self.end
}
}
impl<T: Clone, C: Clone> Span for SimpleSpan<T, C> {
type Context = C;
type Offset = T;
fn new(context: Self::Context, range: Range<Self::Offset>) -> Self {
Self {
start: range.start,
end: range.end,
context,
}
}
fn context(&self) -> Self::Context {
self.context.clone()
}
fn start(&self) -> Self::Offset {
self.start.clone()
}
fn end(&self) -> Self::Offset {
self.end.clone()
}
}
impl<C: Clone, S: Span<Context = ()>> Span for (C, S) {
type Context = C;
type Offset = S::Offset;
fn new(context: Self::Context, range: Range<Self::Offset>) -> Self {
(context, S::new((), range))
}
fn context(&self) -> Self::Context {
self.0.clone()
}
fn start(&self) -> Self::Offset {
self.1.start()
}
fn end(&self) -> Self::Offset {
self.1.end()
}
}
impl<T: Clone> Span for Range<T> {
type Context = ();
type Offset = T;
fn new(_context: Self::Context, range: Range<Self::Offset>) -> Self {
range
}
fn context(&self) -> Self::Context {}
fn start(&self) -> Self::Offset {
self.start.clone()
}
fn end(&self) -> Self::Offset {
self.end.clone()
}
}
pub trait WrappingSpan<T>: Span {
type Spanned;
fn make_wrapped(self, inner: T) -> Self::Spanned;
fn inner_of(spanned: &Self::Spanned) -> &T;
fn span_of(spanned: &Self::Spanned) -> &Self;
}
pub trait SpanWrap<S: WrappingSpan<Self>>: Sized {
fn with_span(self, span: S) -> S::Spanned {
span.make_wrapped(self)
}
}
impl<T, S: WrappingSpan<T>> SpanWrap<S> for T {}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Spanned<T, S = SimpleSpan> {
pub inner: T,
pub span: S,
}
pub type SimpleSpanned<T, U = usize, C = ()> = Spanned<T, SimpleSpan<U, C>>;
impl<T, U: Clone, C: Clone> WrappingSpan<T> for SimpleSpan<U, C> {
type Spanned = SimpleSpanned<T, U, C>;
fn make_wrapped(self, inner: T) -> Self::Spanned {
SimpleSpanned { inner, span: self }
}
fn inner_of(spanned: &Self::Spanned) -> &T {
&spanned.inner
}
fn span_of(spanned: &Self::Spanned) -> &Self {
&spanned.span
}
}
impl<T, S> Deref for Spanned<T, S> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T, S> DerefMut for Spanned<T, S> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}