Rust 写脚手架,Clap你应该知道的二三事( 三 )


文章插图
图片
如果想了解更多关于参数配置 , 可以翻看clap_command-attributes[5]

Rust 写脚手架,Clap你应该知道的二三事

文章插图
图片
2. 编写子命令作为一个功能强大的CLI,我们有时候需要通过定义一些子命令来让我们的目的更加明确 。
如果大家用过我们的f_cli , 那就心领神会了 。
下图是我们f_cli的根据用户提供的参数,默认构建前端项目的命令 。
Rust 写脚手架,Clap你应该知道的二三事

文章插图
图片
在f_cli的实现中,我们就用到了子命令的操作 。
Rust 写脚手架,Clap你应该知道的二三事

文章插图
图片
下面我们来简单实现一个拥有子命令的cli 。在之前代码的基础上,我们只需要将刚才结构体中再新增一个参数 - command并且其类型为实现sumcommad trait的枚举
use clap::{ Parser, Subcommand };#[derive(Parser,Debug)]#[command(version, about)]struct Cli {#[arg(default_value = https://www.isolves.com/it/cxkf/yy/Rust/2024-03-11/"front789")]name: String,#[command(subcommand)]command: Commands}#[derive(Subcommand, Debug, Clone)]enum Commands {Create,Replace,Update,Delete}fn main() {let cli = Cli::parse();println!("Hello, {:?}!", cli);}这样,我们就在上面的基础上拥有了一组子命令(CRUD) 。这样我们就可以在cli中调用对应的子命令然后执行对应的操作了 。
Rust 写脚手架,Clap你应该知道的二三事

文章插图
图片
3. 添加命令标志我们可以继续丰富我们子命令 。上面的我们不是通过一个枚举Commands够了一个组件命令(Create/Replace/Update/Delete)吗 。
有时候,在某一个子命令下 , 还需要收集更多的用户选择 。那么我们就可以将枚举中的值关联成一个「匿名结构体」 。这样,我们就可以针对某个子命令做更深的操作了 。
还是举我们之前的f_cli的例子,在我们通过f_cli create xxx构建项目时,我们可以通过-x来像CLI传递Create所用到的必要信息 。
Rust 写脚手架,Clap你应该知道的二三事

文章插图
图片
use clap::{ Parser, Subcommand };#[derive(Parser,Debug)]#[command(version, about)]struct Cli {#[arg(default_value = https://www.isolves.com/it/cxkf/yy/Rust/2024-03-11/"front789")]name: String,#[command(subcommand)]command: Commands}#[derive(Subcommand, Debug, Clone)]enum Commands {Create{#[arg(default_value = "front789")]name: String,#[arg(default_value = "山西")]address: String,},Replace,Update,Delete}这样我们就对Create进一步处理,并且在create的时候,它会从命令行中寻找对应的name/address信息,并且收集到clap实例中 。
随后,我们就可以在主函数中通过match来匹配枚举信息 , 然后执行相对应的操作 。
Rust 中的匹配是穷举式的:必须穷举到最后的可能性来使代码有效
为了节约代码量,我们通过_占位符来处理其他的逻辑 。
fn main() {let cli = Cli::parse();match cli.command {Commands::Create{name,address} => {println!("我是{},来自:{}", name,address);},_=>(),}}当我们运行cargo run create时,由于我们提供了默认值 , 在控制台就会输出对应的信息 。当然,我们也可以通过-- name xx -- address xx来进行操作 。
有人会觉得输入较长的子命令不是很友好,我们可以通过short = 'n'来为子命令提供一个别名 。同时我们还可以通过help="xxx"设置对应在--help时,提供给用户的帮助信息 。
Rust 写脚手架,Clap你应该知道的二三事

文章插图
图片
对应的代码如下:
#[derive(Subcommand, Debug, Clone)]enum Commands {Create{#[arg(short = 'n',lnotallow="name",help = "用户信息",default_value = https://www.isolves.com/it/cxkf/yy/Rust/2024-03-11/"front789")]name: String,#[arg(short = 'a',lnotallow="address",help = "地址信息",requires = "name",default_value = "山西")]address: String,},Replace,Update,Delete}4. 交互式cli在上一节中我们通过对CLI枚举进行改造,让其能够拥有了子命令的功能 。其实到这步已经能够获取到cli中用户输入的值,并且能够进行下一步的操作了 。
但是呢 , 你是一个精益求精的人 。见多识广的你突然有一个想法,为什么不能像vite/create/next一样 。在触发对应的构建和更新操作后,有一个「人机交互」的过程 。然后,用户可以根据自己的喜好来选择我们cli的内置功能 。这样是不是显的更加友好 。
像我们的f_cli就是这种交互流程 。用户通过人机交互的方式可以选择内置功能 。


推荐阅读