
文章插图
图片
f_cli 选择UI库
那我们就再次用一个简单的例子来介绍一下哇 。
安装新的包首先 , 我们需要安装几个用于交互的包 。
cargo add anyhowcargo add dialoguercargo add console随后 , 就他们就会自动被注入到Cargo.toml中了 。关于anyhow/dialoguer/console我们就不在这里过多介绍了 。大家感兴趣可以去对应的官网查找.- dialoguer[6]
- console[7]
- anyhow[8]
use clap::{ +builder::EnumValueParser,Parser,Subcommand, +ValueEnum };+use dialoguer::{ +console::Term, +theme::ColorfulTheme, +Select +};+use console::style;新增枚举信息前面说过,我们想通过人机交互的方式,在cli运行过程中让用户自己选择我们内置的功能点 。所以,这些内置功能我们可以需要事先设定好 。#[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)]pub enum Name {N1,N2,}#[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)]pub enum Address {A1,A2}处理结构体中参数的默认值既然,已经有了对应的默认值,那么我们就需要限制我们cli中的参数必须是这些内置参数中值 。#[derive(Subcommand, Debug, Clone)]enum Commands {Create{#[arg(short = 'n',lnotallow="name",help = "用户信息",+value_parser = EnumValueParser::<Name>::new(),ignore_case = true)]+name: Option<Name>,#[arg(short = 'a',lnotallow="address",help = "地址信息",requires = "name",+value_parser = EnumValueParser::<Address>::new(),)]+address: Option<Address>,}}上面的配置,见名知意 , 就是从对应的枚举中解析对应的值 。主函数其实,这步的操作和之前是差不多的,我们还是利用match对cli.command进行匹配处理 。不过我们这里又进一步的做了容错处理 。
- 首先判断是否提供子命令
- 在提供子命令的情况下,再判断是否是Craete
fn main() ->anyhow::Result<()> {let cli = Cli::parse();match cli.command {// - 如果有子命令,则根据子命令执行相应的逻辑;Some(command) => {match command {Commands::Create {name,address,} =>operation_params(name,address)?,}},_ => panic!("Fatal: cli为提供参数,退出处理."),}Ok(())}operation_params在main中我们通过match是可以获取到cli中参数的,而此时我们还需要根据参数做进一步的处理 。我们把这个逻辑提取到了一个函数中了 。fn operation_params (name: Option<Name>,address: Option<Address>) -> anyhow::Result<()> {let n = match name {Some(na) => na,None => {multiselect_msg("选择一个姓名:");message("使用上/下箭头进行选择,使用空格或回车键确认 。");let items = vec!["张三", "王五"];let selection = Select::with_theme(&ColorfulTheme::default()).items(&items).default(0).interact_on_opt(&Term::stderr())?;match selection {Some(0) => Name::N1,Some(1) => Name::N2,_ => panic!("Fatal: 用户信息制定错误."),}}};let a = match address {Some(na) => na,None => {multiselect_msg("选择一个地址:");message("使用上/下箭头进行选择,使用空格或回车键确认 。");let items = vec!["太原", "晋中"];let selection = Select::with_theme(&ColorfulTheme::default()).items(&items).default(0).interact_on_opt(&Term::stderr())?;match selection {Some(0) => Address::A1,Some(1) => Address::A2,_ => panic!("Fatal: 地址信息制定错误."),}}};println!("name:{:?},地址:{:?}",n,a);Ok(())}其实上面的逻辑也是比较简单明了的 。我们接收cli中的参数name/address 。因为他们都是枚举类型,所以我们继续用match进行对应值的匹配 。虽然,我们对两个枚举值都做了处理,但是他们的逻辑都是相同的 。
上面的逻辑就是当我们运行子命令时候
- 当提供对应的参数的话 , 那就原封不动的返回对应的值
- 当没有提供对应的参数的话 , 我们就调用dialoguer::Select进行我们预设值的选择 。
推荐阅读
- GitHub顶流"Web OS"——运行于浏览器的桌面操作系统、用户超100万、原生jQuery和JS编写
- 前端开始“锈化”?Vue团队开源JS打包工具:基于Rust、速度极快、尤雨溪主导
- 两年前端经验还不会手写Promise?
- Rust中的数据可视化指南
- 秦岚和迪丽热巴都在海边拍写真,一个苗条惊艳!一个丰腴成熟迷人
- 长得丑演技还烂,满脸写着“关系户”的演员们,谁的审美有问题?
- 线段比例尺怎么画,线段比例尺怎么改写成数值比例尺
- 端午节粽子发朋友圈文案 端午节粽子朋友圈文案怎么写
- 《青春环游记》制片人李佳临患癌,常熬夜到凌晨3点,已写好遗书!
- 读书:有没有和我一样,年初计划都写上减肥,而年底却增肥几斤
