use std::{ops::Deref, sync::Arc};
use crate::{Error, Input, Parse, Span, Spanned, Success, Token};
pub trait Combinator<A>: Sized {
fn apply<I, F>(input: &mut I, parser: F) -> Result<Success<Self, I>, Error<I>>
where
I: Input,
F: FnMut(&mut I) -> Result<Success<A, I>, Error<I>>;
}
impl<T> Combinator<T> for T
where
T: Token,
{
fn apply<I, F>(input: &mut I, mut parser: F) -> Result<Success<Self, I>, Error<I>>
where
I: Input,
F: FnMut(&mut I) -> Result<Success<Self, I>, Error<I>>,
{
parser(input)
}
}
impl Combinator<()> for () {
fn apply<I, F>(input: &mut I, mut parser: F) -> Result<Success<Self, I>, Error<I>>
where
I: Input,
F: FnMut(&mut I) -> Result<Success<(), I>, Error<I>>,
{
parser(input)
}
}
impl<P> Parse for Box<P>
where
P: Parse,
{
type Token = P::Token;
type Output = Box<P::Output>;
fn parse<I>(input: &mut I) -> Result<Success<Self::Output, I>, Error<I>>
where
I: Input<Token = Self::Token>,
{
P::parse(input).map(|res| res.map(Box::new))
}
}
impl<T> Spanned for Box<T>
where
T: Spanned,
{
type Span = T::Span;
fn span(&self) -> Self::Span {
self.deref().span()
}
}
impl<P> Parse for Arc<P>
where
P: Parse,
{
type Token = P::Token;
type Output = Arc<P::Output>;
fn parse<I>(input: &mut I) -> Result<Success<Self::Output, I>, Error<I>>
where
I: Input<Token = Self::Token>,
{
P::parse(input).map(|res| res.map(Arc::new))
}
}
impl<T> Spanned for Arc<T>
where
T: Spanned,
{
type Span = T::Span;
fn span(&self) -> Self::Span {
self.deref().span()
}
}
impl<P> Parse for Option<P>
where
P: Parse,
{
type Token = P::Token;
type Output = Option<P::Output>;
fn parse<I>(input: &mut I) -> Result<Success<Self::Output, I>, Error<I>>
where
I: Input<Token = Self::Token>,
{
let chk = input.save();
match P::parse(input) {
Ok(res) => Ok(res.map(Some)),
Err(err) => {
input.reset(chk);
Ok(Success(None, Some(err)))
}
}
}
}
impl<T, U> Combinator<U> for Option<T>
where
T: Combinator<U>,
{
fn apply<I, F>(input: &mut I, parser: F) -> Result<Success<Self, I>, Error<I>>
where
I: Input,
F: FnMut(&mut I) -> Result<Success<U, I>, Error<I>>,
{
let checkpoint = input.save();
if let Ok(res) = T::apply(input, parser) {
Ok(res.map(Some))
} else {
input.reset(checkpoint);
Ok(None.into())
}
}
}
impl<T> Spanned for Option<T>
where
T: Spanned,
T::Span: Default,
{
type Span = T::Span;
fn span(&self) -> Self::Span {
self.as_ref().map(Spanned::span).unwrap_or_default()
}
}
impl<P> Parse for Vec<P>
where
P: Parse,
{
type Token = P::Token;
type Output = Vec<P::Output>;
fn parse<I>(input: &mut I) -> Result<Success<Self::Output, I>, Error<I>>
where
I: Input<Token = Self::Token>,
{
let mut result = Success::from(vec![]);
let mut chk = input.save();
loop {
match P::parse(input) {
Ok(next_res) => {
let next_item = result.merge(next_res);
result.0.push(next_item);
chk = input.save();
}
Err(err) => {
if err.committed || input.save() != chk {
return Err(match result.1 {
None => err,
Some(e) => err.merge(e),
});
} else {
result.merge(Success((), Some(err)));
break;
}
}
}
}
input.reset(chk);
Ok(result)
}
}
impl<T, U> Combinator<U> for Vec<T>
where
T: Combinator<U>,
{
fn apply<I, F>(input: &mut I, mut parser: F) -> Result<Success<Self, I>, Error<I>>
where
I: Input,
F: FnMut(&mut I) -> Result<Success<U, I>, Error<I>>,
{
let mut result = Success::from(vec![]);
let mut chk = input.save();
loop {
match T::apply(input, &mut parser) {
Ok(next_res) => {
let next_item = result.merge(next_res);
result.0.push(next_item);
chk = input.save();
}
Err(err) => {
if err.committed || input.save() != chk {
return Err(match result.1 {
None => err,
Some(e) => err.merge(e),
});
} else {
result.merge(Success((), Some(err)));
break;
}
}
}
}
input.reset(chk);
Ok(result)
}
}
impl<T> Spanned for Vec<T>
where
T: Spanned,
T::Span: Default,
{
type Span = T::Span;
fn span(&self) -> Self::Span {
let first = self.first().map(Spanned::span).unwrap_or_default();
let last = self.last().map(Spanned::span).unwrap_or_default();
first.enclose(&last)
}
}