Как создать макрос, преобразующий входные данные в кортеж? - PullRequest
0 голосов
/ 21 июня 2020

Я хочу по возможности избегать создания множества пронумерованных функций и дублирования кода. Я пишу программу, которая анализирует файл конфигурации, содержащий строки, подобные приведенным ниже, и я хочу упростить свой logi c для его анализа с помощью некоторых вспомогательных функций.

Мне нужен совет по идиоматическим c Rust подход к этому, чтобы избежать дублирования кода, сохраняя его читабельность. Я предполагаю, что могу ли я использовать макрос, который мог бы каким-то образом преобразовать ввод в блок, который приводит к кортежу, но не знаю, как его записать, включая шаги итерации и преобразования.

Пример ввода

attribute-name
1 2
other-attribute
3 4 5

Текущая реализация синтаксического анализа

/// 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>( ...

Телефонный код

let (width, height) = split_str_into_2(
    input_line, " ", |entry| i32::from_str_radix(entry, 10), &MyError::new("Missing number entry"))?;

1 Ответ

1 голос
/ 22 июня 2020

Я не знаю вашего точного использования, но одна из возможностей, если вы хотите собрать итератор в кортеж, будет Itertools::collect_tuple.

Это пока что реализовано для кортежей до длины 4 . Если вам нужно больше элементов, вы можете попробовать адаптировать подход, принятый в itertools, или зарегистрировать проблему / PR по проекту.

...