Atuin中的Clap实现

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

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

首先观察紫色的这条线部分, 并结合前部在AtuinCmd和client::Cmd添加的subcommand和flatten可以知道, 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::Cmd和import::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
相关推荐
滕州市燕猫虎计算机科技工作室个体工商户2 小时前
《Rust程序设计》学习笔记六:错误处理
rust·学习笔记·rust程序设计·rust学习笔记
达子6665 小时前
RUST 图解 第 3 章:通用编程概念(Common Programming Concepts)
开发语言·算法·rust
对象存储与RustFS13 小时前
HelixDB 上手:Agent 记忆新方案,基于 RustFS 对象存储,附完整 docker-compose 部署示例
后端·rust·开源
Amos_Web13 小时前
Rspack 源码解析(二十):Typed Hook 系统如何靠宏生成
前端·rust·前端框架
Source.Liu15 小时前
【A11】拆分前端,实现多页面方案
前端·rust
Kapaseker15 小时前
别只会 unwrap():Rust Result 的几种实用写法
rust
DongQiShanRen1 天前
玄龙(上):TICK 主循环——意识心跳怎么跳
linux·jvm·数据库·人工智能·数据挖掘·rust
编程序的员1 天前
使用OpenTelemetry来监控Rust应用
运维·rust·monitoring·opentelemetry
对象存储与RustFS2 天前
JuiceFS + 对象存储:把 S3 变成 POSIX 文件系统实测
后端·rust·开源
遇码2 天前
侧边栏一开,AI 画的东西就被挡住了:给白板画布加「真实可见区」计算和相机补偿
人工智能·ai·rust