ast-demangle 0.3.1

Parses mangled names and produces structured results.
Documentation
use crate::mini_parser::generic_tuple::{Tuple1, TupleAppend};
use crate::mini_parser::Parser;

pub struct TupleImpl<P, Q> {
    lhs: P,
    rhs: Q,
}

pub trait AccParser<A, I, C> {
    type Output;

    fn parse(&mut self, acc: A, input: I, context: &mut C) -> Result<(Self::Output, I), ()>;
}

impl<A, I, C> AccParser<A, I, C> for () {
    type Output = A;

    fn parse(&mut self, acc: A, input: I, _context: &mut C) -> Result<(Self::Output, I), ()> {
        Ok((acc, input))
    }
}

impl<A, I, C, P, Q> AccParser<A, I, C> for TupleImpl<P, Q>
where
    A: TupleAppend<P::Output>,
    P: Parser<I, C>,
    Q: AccParser<A::Output, I, C>,
{
    type Output = Q::Output;

    fn parse(&mut self, acc: A, input: I, context: &mut C) -> Result<(Self::Output, I), ()> {
        let (output, input) = self.lhs.parse(input, context)?;

        self.rhs.parse(acc.append(output), input, context)
    }
}

pub trait TupleBuilder {
    type Output;

    fn build(self) -> Self::Output;
}

impl TupleBuilder for () {
    type Output = ();

    fn build(self) -> Self::Output {}
}

impl<T> TupleBuilder for T
where
    T: Tuple1,
    T::Rest: TupleBuilder,
{
    type Output = TupleImpl<T::First, <T::Rest as TupleBuilder>::Output>;

    fn build(self) -> Self::Output {
        let (lhs, rhs) = self.split_first();

        TupleImpl { lhs, rhs: rhs.build() }
    }
}

pub struct Tuple<T>
where
    T: TupleBuilder,
{
    inner: T::Output,
}

impl<I, C, T> Parser<I, C> for Tuple<T>
where
    T: TupleBuilder,
    T::Output: AccParser<(), I, C>,
{
    type Output = <T::Output as AccParser<(), I, C>>::Output;

    fn parse(&mut self, input: I, context: &mut C) -> Result<(Self::Output, I), ()> {
        self.inner.parse((), input, context)
    }
}

pub fn tuple<T>(parsers: T) -> Tuple<T>
where
    T: TupleBuilder,
{
    Tuple { inner: parsers.build() }
}