有没有办法使用 docopt 从命令行传递 u8 的向量?

悲伤的机器

有没有办法让用户提示输入括号内的字节并用逗号或类似的东西分隔?

./main bytes [0, 1, 2, 3, 4, 5]

我设法让它看起来像这样:

./main bytes 0 1 2 3 4 5

这是我的代码:

extern crate docopt;
#[macro_use]
extern crate serde_derive;

use docopt::Docopt;

const USAGE: &'static str = "
    Puzzle Solver.

    Usage:
      puzzle_solver string <text>
      puzzle_solver bytes [<bin>...] 
      puzzle_solver (-h | --help)
      puzzle_solver --version

    Options:
      -h --help     Show this screen.
      --version     Show version.
    ";

#[derive(Debug, Deserialize)]
struct Args {
    cmd_string: bool,
    arg_text: Option<String>,
    cmd_bytes: bool,
    arg_bin: Option<Vec<u8>>,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.deserialize())
        .unwrap_or_else(|e| e.exit());

    println!("ARGS: {:?}", args);
}
特伦特克

这是可能的,但您必须Deserialize手动实施

Vec<u8>已经实现Deserialize,并且该实现不知道包含逗号分隔的括号列表的字符串,也不知道docopt::Deserializer,因为在命令行上传递列表的正常方法是逐个元素。因此,您必须创建一个新类型,该类型将从您想要的格式反序列化。

当然,您也可以实现Deref<Target = Vec<u8>>DerefMutBytes,如果你想要把它作为一个Vec<u8>有些人可能认为这是对 的轻微误用Deref,但在这种情况下可能没问题。

extern crate docopt;
extern crate serde;
#[macro_use]
extern crate serde_derive;

use docopt::Docopt;
use serde::de;
use std::fmt;

const USAGE: &'static str = "
    Puzzle Solver.

    Usage:
      puzzle_solver string <text>
      puzzle_solver bytes <bin>
      puzzle_solver (-h | --help)
      puzzle_solver --version

    Options:
      -h --help     Show this screen.
      --version     Show version.
    ";

#[derive(Debug, Deserialize)]
struct Args {
    cmd_string: bool,
    arg_text: Option<String>,
    cmd_bytes: bool,
    arg_bin: Option<Bytes>,
}

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

impl<'de> de::Deserialize<'de> for Bytes {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: de::Deserializer<'de>,
    {
        struct BytesVisitor;

        impl<'de> de::Visitor<'de> for BytesVisitor {
            type Value = Bytes;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
                write!(formatter, "a bracketed, comma-delimited string")
            }

            fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
                let v = if v.starts_with('[') && v.ends_with(']') {
                    &v[1..v.len() - 1]
                } else {
                    return Err(E::custom(format!("expected a bracketed list, got {:?}", v)));
                };
                let values: Result<Vec<u8>, _> = v.split(",").map(|s| s.trim().parse()).collect();
                Ok(Bytes(values.map_err(E::custom)?))
            }
        }

        deserializer.deserialize_str(BytesVisitor)
    }
}

这是在操场上。这些是我为使其正常工作所做的更改:

  1. 替换[<bin>...]<bin>这样 docopt 将知道寻找单个事物而不是一系列......事物。(如果你不这样做,docopt 实际上只是给你一个空字符串。)
  2. Bytes周围引入 newtype包装器Vec<u8>
  3. 实现serde::de::DeserializeBytes这需要创建一个实现serde::de::Visitortrait的结构,将分离字符串的代码放入其visit_str方法中,并将访问者传递给deserialize_str,这告诉Deserializer期望一个字符串并将其传递给访问者的visit_str

直到快完成时我才意识到它,但您可以visit_seq改为实现,并使其解析bytes [1, 2, 3](不引用列表)。但我不会,因为这违反了命令行约定;如果您无论如何都使用 shell 来拆分参数,那么您应该一路走下去,只接受bytes 1 2 3.

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

有没有办法通过dplyr的`do`函数传递附加参数的向量?

有没有办法确定如何从命令行启动任何程序

有没有办法从命令行展平.pdf图像?

有没有办法从命令行切换勿扰模式?

有没有办法从命令行获取文件元数据?

有没有办法从命令行打开启动Eclipse,例如vscode?

有没有办法从命令行安全地关闭 Chromium?

有没有办法从命令行锁定加密的驱动器?

有没有办法在Windows上从命令行获取当前音量输出?

有没有办法从命令行为 Xcode 项目自动创建方案

有没有办法调试使用Rscript.exe从命令行运行的R脚本

有没有办法通过命令行将jvm args传递给Maven?

有没有办法使用C#获得命令行certreq -accept的功能?

有没有办法从命令行或代码中获得Objective-C版本?

有没有办法从命令行在 Azure Log Analytics 中添加性能计数器

有没有办法知道Java程序是从命令行启动还是从jar文件启动?

有没有办法从命令行更改当前 Terminator 窗口中的布局?

使用图像包装箱时如何获取u8 RGB值的向量?

有没有办法从实现 Read 特性的 Vec<u8> 创建一个 Box ?

有没有办法使包含自身向量的特征?

有没有办法向量化此for循环

有没有办法从一个向量传递 lm 的公式并在另一个向量中获取一组 R2(不使用循环)?

有没有办法将\ r \ n作为C程序的命令行参数传递?

python,unittest:有没有办法将命令行选项传递给应用程序

有没有办法使地图的Clojure向量上的地图使用破坏性绑定?

有没有办法可以使用向量简化下面的代码?

有没有办法跳到Mac Terminal中的命令行命令的较早部分?

有没有办法告诉SeleniumRunner驱动程序在哪里使用命令行?

有没有办法在 Visual Studio 的“命令行参数”启动选项中使用相对路径?