Как использовать StructOpt для анализа аргумента в Vec, не рассматривая его как несколько аргументов? - PullRequest
0 голосов
/ 24 апреля 2018

У меня есть этот код:

#[derive(StructOpt)]
pub struct Opt {
    /// Data stream to send to the device
    #[structopt(help = "Data to send", parse(try_from_str = "parse_hex"))]
    data: Vec<u8>,
}

fn parse_hex(s: &str) -> Result<u8, ParseIntError> {
    u8::from_str_radix(s, 16)
}

Это работает для myexe AA BB, но мне нужно принять myexe AABB в качестве ввода.

Есть ли способ передать пользовательский парсерstructopt чтобы разобрать AABB в Vec<u8>?Мне нужно разобрать только вторую форму (без пробела).

Я знаю, что могу сделать это в 2 шага (сохранение в String в структуре и затем проанализировать ее, но мне нравится идея, что мой *У 1014 * есть окончательный тип для всего.

Я пробовал синтаксический анализатор следующим образом:

fn parse_hex_string(s: &str) -> Result<Vec<u8>, ParseIntError>

Макрос StructOpt паникует из-за несоответствия типов, потому что кажется, что он производит Vec<Vec<u8>>.

1 Ответ

0 голосов
/ 24 апреля 2018

StructOpt делает различие, что Vec<T> всегда будет сопоставляться с несколькими аргументами:

Vec<T: FromStr>

список опций или других позиционных аргументов

.takes_value(true).multiple(true)

Это означает, что вам нужен один тип для представления ваших данных.Замените ваш Vec<u8> новым типом:

#[derive(Debug)]
struct HexData(Vec<u8>);

#[derive(Debug, StructOpt)]
pub struct Opt {
    /// Data stream to send to the device
    #[structopt(help = "Data to send")]
    data: HexData,
}

Это приводит к ошибке:

error[E0277]: the trait bound `HexData: std::str::FromStr` is not satisfied
  --> src/main.rs:16:10
   |
16 | #[derive(StructOpt)]
   |          ^^^^^^^^^ the trait `std::str::FromStr` is not implemented for `HexData`
   |
   = note: required by `std::str::FromStr::from_str`

Давайте реализуем FromStr:

impl FromStr for HexData {
    type Err = hex::FromHexError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        hex::decode(s).map(HexData)
    }
}

И этоработы:

$ cargo run -- DEADBEEF
HexData([222, 173, 190, 239])

$ cargo run -- ZZZZ
error: Invalid value for '<data>': Invalid character 'Z' at position 0
...