从输入中的任何地方解析 Structopt 标志
Parse Structopt flag from anywhere in the input
我希望能够在我的命令行工具中使用 'universal' 标志,它使用 StructOpt
。也就是说,如果我有一个标志(例如 --debug
),我希望它的行为相同,而不管该标志在输入中的什么位置:
$ mycli --debug alpha
$ mycli alpha --debug
(alpha
和 --debug
在此示例中只是有用的占位符;实际的子命令和标志会有所不同。)
实际行为:
$ 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
预期行为:
$ 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
代码:
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
文件(上面的例子不会工作 w/o structopt
依赖):
[package]
name = "scratch-rust"
version = "0.1.0"
edition = "2018"
[dependencies]
structopt = "*"
有没有一种方法可以做到这一点而无需在子命令的每个级别复制 'universal' 标志?
Clap 有 global()
method for arguments that does what you want. You can access this method vis Structopt using raw attributes:
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
属性)
应用程序现在可以按照您希望的方式运行:
$ 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.
我希望能够在我的命令行工具中使用 'universal' 标志,它使用 StructOpt
。也就是说,如果我有一个标志(例如 --debug
),我希望它的行为相同,而不管该标志在输入中的什么位置:
$ mycli --debug alpha
$ mycli alpha --debug
(alpha
和 --debug
在此示例中只是有用的占位符;实际的子命令和标志会有所不同。)
实际行为:
$ 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
预期行为:
$ 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
代码:
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
文件(上面的例子不会工作 w/o structopt
依赖):
[package]
name = "scratch-rust"
version = "0.1.0"
edition = "2018"
[dependencies]
structopt = "*"
有没有一种方法可以做到这一点而无需在子命令的每个级别复制 'universal' 标志?
Clap 有 global()
method for arguments that does what you want. You can access this method vis Structopt using raw attributes:
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
属性)
应用程序现在可以按照您希望的方式运行:
$ 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.