我尝试构建cli,它应该将<command_name>
作为第一个参数,将<path_to_file>
作为最后一个参数,并在这两个参数之间使用选项,因此在控制台中的调用如下所示:
programm command_one --option True file.txt
我有这样的设置:
// ./src/main.rs
use clap::{Args, Parser, Subcommand};
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Args, Debug)]
struct CommandOneArgs {
file: String,
#[arg(short, long)]
option_for_one: Option<String>,
}
#[derive(Args, Debug)]
struct CommandTwoArgs {
file: String,
#[arg(short, long)]
option_for_two: Option<String>,
}
#[derive(Subcommand, Debug)]
enum Commands {
CmdOne(CommandOneArgs)
CmdTwo(CommandTwoArgs)
}
fn main() {
let args = Cli::parse();
match &args.command {
Commands::CmdOne(cmd_args) => {println!({:?}, cmd_args)}
Commands::CmdTwo(cmd_args) => {println!({:?}, cmd_args)}
_ => {}
}
但这里有一个问题,我没有解决:
实际上,在match的分支中,我会用获得的参数调用一些函数;
然而,我需要为所有命令做好准备,例如从路径读取文件
因此,在匹配表达式之前,我需要提取file
属性:
fn main() {
let args = Cli::parse();
/// something like that
// let file_path = args.command.file;
// println!("reading from: {}", file_path)
match &args.command {
Commands::CmdOne(cmd_args) => {println!({:?}, cmd_args)}
Commands::CmdTwo(cmd_args) => {println!({:?}, cmd_args)}
_ => {}
}
我不能像评论的那样做。
而且我不能将位置参数添加到Cli
结构体,因为接口看起来像:programm <POSITIONAL ARG> command_one ...
我假设我应该使用泛型,但我不知道如何使用。
1条答案
按热度按时间qvsjd97n1#
将获取
file
参数值的逻辑抽象到Commands
和Cli
上的方法中是否是您的一个选项?如果运行
cargo run -- cmd-one hello
,则打印hello
。