Reputation: 906
I want to avoid creating many numbered functions and duplicated code if possible. I'm writing a program that is parsing a config file containing lines like the following and I want to simplify my logic for parsing it with some helper functions.
I would like advice on the idiomatic Rust way of approaching this to avoid code duplication while keeping it readable. My best guess is if I could use a macro that could somehow convert the input into a block that results in a tuple but don't know how to write that while including the iteration and transformation steps.
Example Input
attribute-name
1 2
other-attribute
3 4 5
Current parsing implementation
/// Splits `s` into two values, using `pattern` to find the split. If not enough values
/// are present, `missing_err` is returned.
/// It then `transform`s each entry, returning the result as a tuple
fn split_str_into_2<'a, T, E>(
s: &'a str,
pattern: &str,
transform: &dyn Fn(&str) -> T,
missing_err: &E,
) -> Result<(T, T), E> where E: Copy {
let mut split = s.splitn(2, pattern);
Ok((
transform(split.next().ok_or_else(|| *missing_err)?),
transform(split.next().ok_or_else(|| *missing_err)?),
))
}
/// Same as above but parses into a tuple of 3
fn split_str_into_3<'a, T, E>( ...
Calling Code
let (width, height) = split_str_into_2(
input_line, " ", |entry| i32::from_str_radix(entry, 10), &MyError::new("Missing number entry"))?;
Upvotes: 0
Views: 491
Reputation: 35983
I do not know your exact use, but one possibility if you want to collect an iterator into a tuple would be Itertools::collect_tuple
.
This, for now is implemented for tuples up to length 4. If you need more elements, you could try adapting the approach taken in itertools
or filing an issue/PR on the project.
Upvotes: 1