rust-bakery / nom

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

Ergonomics of `alt()` taking tuple versus slice #1720

Closed t-mart closed 1 month ago

t-mart commented 5 months ago

Is there a reason alt() cannot take a slice of child parsers?

Instead, it takes a List, which is any of the 1- to 21-tuple implementations.

This is fine when the format for which you are trying to parse is known at compile-time/statically, but unusable when the format is only known at runtime.

For example, I'm writing a software-version bumper right now, and the user provides both their arbitrary format (e.g. yyyy.patch) and their current version (e.g. 2024.5) as inputs to my package/program. First, I have a parser for the format string (which is static-defined), but then I need to create a new parser from its result for the actual version string, which is runtime-defined. Therefore, this second parser cannot be made from a tuple.

I have been able to work around this by continually building a parser up in a "reduce" fashion, something like

parsers.reduce(|acc, p| acc.or(p))

(I believe that applying pairwise or() calls has the same effect as alt(), right?) Nonetheless, it's cumbersome, especially with the type annotations, for a newer Rust user like me: plenty of Box, dyn, lifetimes, Sized, etc.

So, I wonder why there isn't a version of alt that could take in a dynamically sized slice of child parsers.

Prerequisites

epage commented 5 months ago

alt for arrays was added in #1556 but that was after the start of 8.0. I've not seen any indication of how much remaining work Geal intends for the 8.0 release.

epage commented 5 months ago

Hmm, that is still just for a fixed size array and it sounds like you don't know the size of your array until runtime, right?

Geal commented 1 month ago

impemented in https://github.com/rust-bakery/nom/pull/1754, this will ship in nom 8, thank you for the suggestion