marser 0.1.0

Parser combinator toolkit with matcher-level backtracking and rich error reporting.
//! AI assistance: this file was written with AI assistance. The maintainer reviewed it and did not find errors.
//!
//! Regression: [`marser::parser::Memoized`] must accept parser outputs that borrow the input (`'src`).

use std::rc::Rc;

use marser::capture;
use marser::parser::{Parser, ParserCombinator};

fn letter_word<'src>() -> impl Parser<'src, &'src str, Output = Rc<&'src str>> + Clone {
    capture!(
        bind_slice!(
            (
                marser::one_of::one_of(('a'..='z', 'A'..='Z')),
                marser::matcher::many(marser::one_of::one_of((
                    'a'..='z',
                    'A'..='Z',
                    '0'..='9',
                ))),
            ),
            slice as &'src str
        ) => slice
    )
    .map_output(Rc::new)
    .memoized()
}

#[test]
fn memoized_parser_with_borrowed_output_parse_str() {
    let p = letter_word();
    let (a, errs_a) = p.parse_str("hello").expect("first parse");
    assert!(errs_a.is_empty());
    let (b, errs_b) = p.parse_str("hello").expect("second parse");
    assert!(errs_b.is_empty());
    assert_eq!(*a, "hello");
    assert_eq!(*b, "hello");
}