0

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"))?;
E_net4
  • 27,810
  • 13
  • 101
  • 139
quittle
  • 856
  • 2
  • 10
  • 19

1 Answers1

1

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.

phimuemue
  • 34,669
  • 9
  • 84
  • 115