rust - Clap - 具有可能共享默认值集的子命令?

标签 rust clap

我已经在这个问题上兜了一段时间了,但没有找到好的解决方案:

我在同一个代码库中有很多模拟。我试图成为一个成年人,并使用命令行参数来选择运行哪个模拟以及使用什么参数。问题是许多参数在不同的模拟之间共享,并且一些参数集被传递给共享组件。

例如,在下面我有三个模拟,其中两个共享“线程”参数子集,另外两个共享 MazeCli参数子集, Maze 需要它特征。 (总的来说,还有更多的争论和组合。)

use clap::*;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Cli {
    #[command(subcommand)]
    sim: Simulation,
}

#[derive(Subcommand, Debug)]
enum Simulation {
    Maze {
        maze_args: MazeCli,
        thread_args: ThreadCli,
    },
    ThreadedMaze {
        maze_args: MazeCli,
    },
    Threaded {
        thread_args: ThreadCli,
    },
}

trait Maze {
    fn new(args: MazeCli) -> Self;
}

#[derive(Args, Debug, Clone)]
struct MazeCli {
    squares: usize,
    openness: f64,
}

#[derive(Args, Debug, Clone)]
struct ThreadCli {
    threads: usize,
}
fn main() {
    let config = Cli::parse();
    println!("{:?}", config);
}

该版本失败,因为它需要 MazeCliThreadCli实现ValueEnum (据我所知 - 实际的错误很长而且没有帮助)。但是,无法为结构派生 ValueEnum。我尝试了一些其他方法,但没有得到任何编译结果。

我可以将所有事情作为一个平面参数列表来完成,但是错误消息不会告诉您所运行的特定子命令的预期内容。

我可以手动指定每个列表,但这是一堆样板文件,尤其是考虑到默认值时。

正确的做法是什么? clap 到底支持什么吗?

奖励问题:

  • 如果这完全可行,是否有任何方法可以让特定子命令覆盖其特定情况的通用默认值(例如,如果一个模拟默认情况下需要两倍于标准的线程数。)
  • 我可以做 default值以某种方式回落到 Default该结构的特征实现?

最佳答案

使用#[命令(展平)]:

#[derive(Subcommand, Debug)]
enum Simulation {
    Maze {
        #[command(flatten)]
        maze_args: MazeCli,
        #[command(flatten)]
        thread_args: ThreadCli,
    },
    ThreadedMaze {
        #[command(flatten)]
        maze_args: MazeCli,
    },
    Threaded {
        #[command(flatten)]
        thread_args: ThreadCli,
    },
}

Can I make the default values somehow fall back to a Default trait implementation for that struct?

使用不带参数的default_value_t。默认为 Default::default():

#[derive(Args, Debug, Clone)]
struct MazeCli {
    #[arg(long, default_value_t)]
    squares: usize, // Will be optional with a default of 0
    openness: f64,
}

If this is possible at all, is there any way for specific subcommands to override generic defaults for their specific case (like, if one simulation wanted twice as many threads as the norm by default.)

我认为如果不使用单独的结构这是不可能的。

关于rust - Clap - 具有可能共享默认值集的子命令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75290258/

相关文章:

rust - Rust 中的可变借用

function - 如何在不使用命令行的情况下使用具有 CLAP 的 Rust crate 的功能?

rust - 如何防止最后一个参数需要用 clap 引用?

rust - 在 clap cli 中返回错误并优雅退出

multithreading - Rust多线程HTTP请求,是否从响应中获取所有数据?

rust - 为什么我不能比较两个不同类型的整数?

rust - 使用带有Self的Rust取消引用运算符&* vs *?

rust - Clap 无法解析 YAML 文件 : failed to convert YAML String ("1") value to a string

rust - 如何在不需要显式值的情况下使一个论点暗示另一个论点? (--foo,不是--foo true)

rust - 在单个表达式中对同一变量的第二次锁定无限期地阻塞