rust-bakery / nom

Rust parser combinator framework
MIT License
9.18k stars 792 forks source link

Add a fold equivalent of separated_list0/separated_list1 #1627

Open pedantic79 opened 1 year ago

pedantic79 commented 1 year ago

I wrote my own version of this for advent of code after I realized there wasn't a built-in way.

Essentially this is like separated_list0/separated_list1, but with an init and g parameter like fold_many0.

This makes it very flexible to parse separated lists and avoid needing to allocate, unless required.

My proposal would be to add a fold_separated_list0 and fold_separated_list1.

pub fn fold_separated_list0<I, O, O2, E, F, G, H, R, S>(
    mut sep: S,
    mut f: F,
    mut init: H,
    mut g: G,
) -> impl FnMut(I) -> IResult<I, R, E>
where
    I: Clone + InputLength,
    F: Parser<I, O, E>,
    S: Parser<I, O2, E>,
    E: ParseError<I>,
    G: FnMut(R, O) -> R,
    H: FnMut() -> R,

Essentially the code would be the same as separated_list0, except for the Vec::new() we call init(), and instead of Vec::push() we call g(). With these code changes, separated_list0 could be written in terms of fold_separated_list0. Just pass the appropriate Vec methods for init and g.

fold_separated_list1 would be based on separated_list1, with the same additional parameters.

Thoughts? Suggestions?