Разбор вектора FromStr, разделенного u8, из BufRead

Мне нужно прочитать вектор, например, целые числа из потока, обычно из стандартного ввода, но иногда и из файла. Ввод всегда меньше мегабайта и иногда разделяется запятыми, а иногда и новой строкой.

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

pub fn parse_vector<T: BufRead, S: FromStr>(buf: T, sep: u8) -> Result<Vec<S>, String> {
    buf.split(sep)
        .enumerate()
        .filter_map(|(i, entry)| {
            let entry_nr = i + 1;

            let entry = match entry.map(String::from_utf8) {
                Err(e) => return Err(format!("Cannot read entry {}, {}.", entry_nr, e)).into(),
                Ok(Err(e)) => return Err(format!("Cannot read entry {}, {}.", entry_nr, e)).into(),
                Ok(Ok(v)) => v,
            };

            let trimmed = entry.trim();
            if trimmed.is_empty() {
                None
            } else {
                Some(
                    trimmed
                        .parse::<S>()
                        .map_err(|_| format!("Cannot parse entry {}: '{}'", entry_nr, entry)),
                )
            }
        })
        .collect()
}

Приведенный выше код работает, насколько я могу судить, но мне интересно, есть ли лучший способ справиться с беспорядком в match выражение. Функции from_utf8 и split возвращают разные типы ошибок, но оба реализуют Display так что, может быть, есть какой-нибудь элегантный способ устранить там дублирование кода, о котором я не знаю (я новичок в ржавчине, пришедший из С ++).

  • Как я могу сделать этот код более читабельным?
  • Считается плохой практикой возвращаться String как тип ошибки?

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *