use crate::*;
use core::{fmt::Debug, ops::{Deref, Range}};
#[derive(Debug, Clone)]
pub struct Span<X> {
pub value: X,
pub range: Range<usize>,
}
pub trait ToSpan: Sized {
fn span(self, range: core::ops::Range<usize>) -> Span<Self>;
}
impl<X> ToSpan for X {
fn span(self, range: core::ops::Range<usize>) -> Span<Self> {
Span { value: self, range }
}
}
impl<X> Span<X> {
pub fn map<Y>(self, f: impl FnOnce(X) -> Y) -> Span<Y> {
Span { value: f(self.value), range: self.range }
}
}
impl<X> Span<X> {
pub fn inner_ref<Y: ?Sized>(&self) -> Span<&Y> where X: AsRef<Y> {
Span { value: self.value.as_ref(), range: self.range.clone() }
}
}
impl<X> Deref for Span<X> {
type Target = X;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl<const GROUP: usize, const ERROR: bool, T> ParseImpl<GROUP, ERROR> for Span<T>
where T: ParseImpl<GROUP, ERROR>
{
fn parse_impl(
input: &str, end: usize,
depth: usize,
first: bool,
trace: &mut Vec<usize>,
stack: &mut Vec<Tag>,
) -> Result<usize, ()> {
<T as ParseImpl<GROUP, ERROR>>::parse_impl(input, end, depth, first, trace, stack)
}
}
impl<Extra, T> AstImpl<Extra> for Span<T>
where T: AstImpl<Extra>,
Extra: Copy,
{
fn ast<'a>(
input: &'a str,
stack: &'a [Tag],
with: Extra
) -> (&'a [Tag], Self) {
let range = stack[stack.len()-1].span.clone();
let (rest, value) = T::ast(input, stack, with);
(rest, Span { value, range })
}
}