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
相关推荐
芳草萋萋鹦鹉洲哦3 小时前
【vue3+tauri+rust】如何实现下载文件mac+windows
windows·macos·rust
寻月隐君11 小时前
Rust 异步编程实践:从 Tokio 基础到阻塞任务处理模式
后端·rust·github
萧曵 丶15 小时前
Rust 中的返回类型
开发语言·后端·rust
浪裡遊17 小时前
Sass详解:功能特性、常用方法与最佳实践
开发语言·前端·javascript·css·vue.js·rust·sass
受之以蒙18 小时前
Rust & WASM 之 wasm-bindgen 基础:让 Rust 与 JavaScript 无缝对话
前端·笔记·rust
Elixin18 小时前
第一章:环境搭建
rust
Pomelo_刘金2 天前
Rust 宣布发布1.88.0
rust
寻月隐君2 天前
告别 Vec!掌握 Rust bytes 库,解锁零拷贝的真正威力
后端·rust·github
大卫小东(Sheldon)2 天前
GIM 1.5发布了! 支持Windows系统了
git·ai·rust
寻月隐君2 天前
告别竞态条件:基于 Axum 和 Serde 的 Rust 并发状态管理最佳实践
后端·rust·github