Atuin中的Clap实现

之前学习了Rust中的Clap crate, 前几天又接触了Rust实现的一个命令行记录工具Atuin, 他的命令行参数就是使用Clap实现, 并且参数众多, 做了不同的分层. 今天就扒一扒Atuin的实现方式, 加深一下对Clap的理解.

下图是整理的Atuin部分命令配置:

首先观察紫色的这条线部分, 并结合前部在AtuinCmdclient::Cmd添加的subcommandflatten可以知道, history应该是最上层的命令, 这从帮助信息中可以看到. 再观察紫色框中的内容, 可以知道history会有 start, end, list, last这些命令, 同时需要输入的参数是, command, id, cwd, session等.

再观察酒红色这一部分, 这里使用的是Parser派生. 同时命令参数的类型是enum, 没有附加数据. 这些命令每次只能指定一个, 并且不带有参数.

接下来看绿色方框的部分, 这里使用Commands类型又多做了一层封装. 如果换成红色方框的结构, 也可以编译通过. 在Commands中的类型是命令, 而在比如login::Cmd中的类型就是参数, 使用的是Parser派生.

总结:

Atuin的代码中, 可以看到它是使用#[command(flatten)] #[command(subcomannd)] #[derive(Subcommand)] 来完成层级结构的规划的.

  • 其中 #[command(flatten)]是将字命令提升一级, 相当于用子命令替换了#[command(flatten)]所在的参数.
  • #[command(subcomannd)]#[derive(Subcommand)]组合完成子命令的创建.

同时可以看到的是 #[derive(Parser)]#[derive(Args)]的使用.

在只有具体参数选项的结构中, 使用的是#[derive(Parser)], 比如login::Cmdimport::Cmd. Clap crate的文档中对Parser的解释就是

Parse command-line arguments into Self.

将参数解析到Self(我理解可以是enum或者struct)当中. 也就是最后需要完成参数解析了.

Args的解释是

Parse a set of arguments into a user-defined container.

Implementing this trait lets a parent container delegate argument parsing behavior to Self. with:

  • #[command(flatten)] args: ChildArgs: Attribute can only be used with struct fields that impl Args.
  • Variant(ChildArgs): No attribute is used with enum variants that impl Args.(适用当前account::Cmd的情况)

Subcommand的解释是

Parse a sub-command into a user-defined enum.

Implementing this trait lets a parent container delegate subcommand behavior to Self. with:

  • #[command(subcommand)] field: SubCmd: Attribute can be used with either struct fields or enum variants that impl Subcommand.
  • #[command(flatten)] Variant(SubCmd): Attribute can only be used with enum variants that impl Subcommand.

从两个官方给出的解释可以看到, Args是解析参数集合到用户定义的容器中(只要求容器类型), Subcommand是解析子命令到用户定义的枚举中(只能是枚举). 还有的不同是(这块还没理解到, 后面补充)

rust 复制代码
#[command(flatten)]
args: ChildArgs  --> ChildArgs必须是实现了Args的struct

#[command(flatten)]
Variant(SubCmd)  --> SubCmd必须是实现了Subcommand的enum
相关推荐
楼兰公子19 小时前
buildroot 在编译rust时裁剪平台类型数量的方法
开发语言·后端·rust
Rust研习社1 天前
开源项目里的 deny.toml 是什么?
后端·rust·编程语言
铭毅天下1 天前
当搜索引擎遇上 Rust——深度解读下一代实时搜索引擎 INFINI Pizza
开发语言·后端·搜索引擎·rust
咸甜适中1 天前
rust语言学习笔记Trait之Default(默认值)
笔记·学习·rust
容智信息2 天前
AI Agent(智能体)的输出格式应该从 Markdown 转向 HTML吗?
前端·人工智能·rust·编辑器·html·prompt
Rust研习社2 天前
Rust Clippy 实用指南:写出更优雅、安全的 Rust 代码
后端·rust·编程语言
yangyongdehao302 天前
两天用AI+rust撸了一款本地批量去水印软件,30MB,效果能打
ai作画·rust
nudt_qxx2 天前
NVIDIA 正式开源cuda-oxide!Rust 编写 CUDA 内核新范式!
rust
小杍随笔3 天前
【Rust桌面革命:Tauri×Dioxus——架构对决、实战拆解与2026选型杀招】
开发语言·架构·rust