首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从输入中的任何位置解析Structopt标志

从输入中的任何位置解析Structopt标志
EN

Stack Overflow用户
提问于 2021-07-05 05:46:05
回答 1查看 77关注 0票数 0

我希望能够在我的命令行工具中使用“通用”标志,它使用StructOpt。也就是说,如果我有一个标志(如--debug),我希望它的行为与该标志在输入中的位置无关:

代码语言:javascript
复制
$ mycli --debug alpha
$ mycli alpha --debug

(在本例中,alpha--debug只是有用的占位符;实际的子命令和标志将是不同的。)

实际行为:

代码语言:javascript
复制
$ cargo run -- --debug alpha                                                                                               nford 14:36:32
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/scratch-rust --debug alpha`
Debug mode enabled!
Alpha subcommand selected.
$ cargo run -- alpha --debug                                                                                               nford 14:36:27
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/scratch-rust alpha --debug`
error: Found argument '--debug' which wasn't expected, or isn't valid in this context

USAGE:
    scratch-rust alpha

预期行为:

代码语言:javascript
复制
$ cargo run -- --debug alpha                                                                                               nford 14:36:32
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/scratch-rust --debug alpha`
Debug mode enabled!
Alpha subcommand selected.
$ cargo run -- alpha --debug       
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/scratch-rust --debug alpha`
Debug mode enabled!
Alpha subcommand selected.

这是我的main.rs代码:

代码语言:javascript
复制
use std::str::FromStr;
use structopt::StructOpt;
use std::io::{Error, ErrorKind};

#[derive(Debug, StructOpt)]
/// Specific task being executed; one task might imply others, depending on flags.
pub enum Subcommand {
    Alpha,
    Omega,
}

impl FromStr for Subcommand {
    type Err = Error;
    fn from_str(subcommand_input: &str) -> Result<Self, Self::Err> {
        match subcommand_input {
            "alpha" => Ok(Subcommand::Alpha),
            "omega" => Ok(Subcommand::Omega),
            _ => Err(Error::new(ErrorKind::Other, "Unrecognized subcommand.")),
        }
    }
}

#[derive(Debug, StructOpt)]
#[structopt(
    name = "Minimal Example CLI",
    about = "A minimal example of multi-location command line inputs.",
)]
pub struct CLIOpts {
    /// Set logging to verbose mode.
    // short and long flags (-d, --debug) will be deduced from the field's name
    #[structopt(short, long)]
    pub debug: bool,

    #[structopt(subcommand)]
    pub cmd: Subcommand,
}


fn main() {
    let args = CLIOpts::from_args();
    if args.debug {
        println!("Debug mode enabled!");
    }
    match args.cmd {
        Subcommand::Alpha => println!("Alpha subcommand selected."),
        Subcommand::Omega => println!("Omega subcommand selected."),
    }
}

这是我的Cargo.toml文件(上面的例子在没有structopt依赖的情况下不起作用):

代码语言:javascript
复制
[package]
name = "scratch-rust"
version = "0.1.0"
edition = "2018"

[dependencies]
structopt = "*"

有没有一种方法可以做到这一点,而不是在每个子命令层级上复制“通用”标志?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-05 20:30:46

Clap有一个用于参数的global()方法,它可以执行您想要的操作。您可以使用raw attributes访问此方法

代码语言:javascript
复制
pub struct CLIOpts {
    /// Set logging to verbose mode.
    // short and long flags (-d, --debug) will be deduced from the field's name
    #[structopt(short, long, global = true)]
    pub debug: bool,

    #[structopt(subcommand)]
    pub cmd: Subcommand,
}

(注意为debug添加的global属性)

应用程序现在可以按您希望的方式工作:

代码语言:javascript
复制
$ cargo run -- --debug alpha
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/scratch-rust --debug alpha`
Debug mode enabled!
Alpha subcommand selected.
$ cargo run -- alpha --debug
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/scratch-rust alpha --debug`
Debug mode enabled!
Alpha subcommand selected.
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68249011

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档