9

我有这个代码:

#[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给解析AABBVec<u8>? 我只需要解析第二种形式(没有空格)。

我知道我可以分两步完成(存储到String结构中的 a 然后解析它,但我喜欢我Opt的所有东西都有最终类型的想法。

我尝试了这样的解析器:

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

宏对类型不匹配感到恐慌,StructOpt因为它似乎会产生一个Vec<Vec<u8>>.

4

1 回答 1

9

StructOpt 区分 aVec<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
于 2018-04-24T16:20:36.263 回答