parsy 0.2.1

An easy-to-use, efficient parser combinators library
Documentation
use std::marker::PhantomData;

use crate::{parser::Parser, PResult, ParserInput};

#[derive(Debug)]
pub enum DebugType<'a, 'b, T> {
    Input(&'a ParserInput<'b>),
    Result(&'a PResult<T>),
}

pub struct Debugging<T, P: Parser<T>, F: for<'a, 'b> Fn(DebugType<'a, 'b, T>) + Clone> {
    parser: P,
    debugger: F,
    _t: PhantomData<T>,
}

impl<T, P: Parser<T>, F: for<'a, 'b> Fn(DebugType<'a, 'b, T>) + Clone> Debugging<T, P, F> {
    pub fn new(parser: P, debugger: F) -> Self {
        Self {
            parser,
            debugger,
            _t: PhantomData,
        }
    }
}

impl<T, P: Parser<T> + Clone, F: for<'a, 'b> Fn(DebugType<'a, 'b, T>) + Clone> Clone
    for Debugging<T, P, F>
{
    fn clone(&self) -> Self {
        Self {
            parser: self.parser.clone(),
            debugger: self.debugger.clone(),
            _t: self._t,
        }
    }
}

impl<T, P: Parser<T>, F: for<'a, 'b> Fn(DebugType<'a, 'b, T>) + Clone> Parser<T>
    for Debugging<T, P, F>
{
    fn parse_inner(&self, input: &mut ParserInput) -> PResult<T> {
        (self.debugger)(DebugType::Input(input));

        let result = self.parser.parse(input);

        (self.debugger)(DebugType::Result(&result));

        result
    }
}