-
Notifications
You must be signed in to change notification settings - Fork 809
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I want to implement separated_tuple
for 8.0
#1718
Comments
For myself, I find there are a lot of unpredicatble ways I want to skip fields in a tuple. Having something like https://docs.rs/combine/latest/combine/macro.struct_parser.html that also applies to tuples could help and be a more general form of this proposed combinator. |
Hello, @BGR360! I don't think there's much need to come up with a fn separated_tuple(s: &str) -> IResult<&str, Vec<&str>> {
map(
separated_list1(
multispace1,
alt((tag("thing1"), tag("thing2"), tag("thing3"))),
),
|x| x,
)(s)
} It's easy to def a function with same functions while no extra FULL CODES BELOW: use nom::{
branch::alt, bytes::complete::tag, character::complete::multispace1, combinator::map,
multi::separated_list1, IResult,
};
fn separated_tuple(s: &str) -> IResult<&str, Vec<&str>> {
map(
separated_list1(
multispace1,
alt((tag("thing1"), tag("thing2"), tag("thing3"))),
),
|x| x,
)(s)
}
fn main() {
assert_eq!(
separated_tuple("thing1 thing2 thing3").unwrap().1,
vec!["thing1", "thing2", "thing3"]
);
} |
@coalooball That will not work when the tuple elements are not of the same type. Plus, even if they were the same type, this doesn't provide any type-safe guarantee that I'm parsing exactly N things. |
What are your thoughts on the more general idea of let (i, (value1, value2, value3)) = seq!(
thing1,
_: space1,
thing2,
_: space1,
thing3,
).parse(i)?; |
Regarding the first point, the method I provided allows heterogeneous things: fn separated_tuple(s: &str) -> IResult<&str, Vec<&str>> {
map(
separated_list1(
multispace1,
alt((
tag("thing1"),
delimited(tag("\""), alphanumeric1, tag("\"")),
tag_no_case("thing3"),
)),
),
|x| x,
)(s)
}
assert_eq!(
separated_tuple("THING3 thing2 \"thing1\"").unwrap().1,
vec!["THING3", "thing2", "thing1"]
); Concerning the second point, I don t understand |
I prefer this: let (i, parsers:iter) = seq!(seperated_parser, permutational_parsers:iter).parse(i)?; |
@coalooball all of those parsers share the same return type, fn thing1(input: &str) -> IResult<&str, Thing1> {...}
fn thing2(input: &str) -> IResult<&str, Thing2> {...}
fn thing3(input: &str) -> IResult<&str, Thing3> {...} It's not possible to use
The output of The output of
@epage A macro that supports discarding arbitrary elements in a sequence is definitely more flexible than my idea of But IMO my idea aligns with the |
I'm using
nom
for Advent of Code 2023 and a pattern I keep using over and over again is "whitespace-separated tuple".I ended up implementing a
separated_tuple
combinator so that code can be much cleaner:Here is my ugly, undocumented implementation that I'm using for AoC.
I think the implementation is complex enough and useful enough to warrant inclusion in
nom
rather than in a third party utility library likenom-supreme
.I would like to contribute a cleaner, more user-ready implementation and submit a pull request.
However, after cloning the repo, I noticed that an 8.0.0 is in the works with lots of changes. So my question to you is:
how would a
separated_tuple
combinator best fit into 8.0.0?If you give me an idea for how to implement it in the 8.0 paradigm, I will happily send out a PR.
The text was updated successfully, but these errors were encountered: