文盘Rust——起手式,CLI程序
来点感性认识
clone 项目
git clone https://github.com/jiashiwen/interactcli-rs.git
cd interactcli-rs命令行模式
cargo run requestsample baidu
交互模式
cargo run -- -i
interact-rs> requestsample baidu
四步做个CLI
.
├── examples
├── log
├── logs
└── src
├── cmd
├── commons
├── configure
├── interact
├── logger
└── request
定义命令 cmd 模块用于定义命令以及相关子命令,requestsample.rs 中定义了访问百度的命令
use clap::Command;
pub fn new_requestsample_cmd() -> Command<'static> {
clap::Command::new("requestsample")
.about("requestsample")
.subcommand(get_baidu_cmd())
}
pub fn get_baidu_cmd() -> Command<'static> {
clap::Command::new("baidu").about("request www.baidu.com")
}new_requestsample_cmd 函数定义了命令 "requestsample",get_baidu_cmd 函数定义了 requestsample 的子命令 baidu
注册命令 src/cmd/rootcmd.rs 文件中定义了命令树,可以在此注册定义好的子命令
lazy_static! {
static ref CLIAPP: clap::Command<'static> = clap::Command::new("interact-rs")
.version("1.0")
.author("Your Name." )
.about("command line sample")
.arg_required_else_help(true)
.arg(
Arg::new("config")
.short('c')
.long("config")
.value_name("FILE")
.help("Sets a custom config file")
.takes_value(true)
)
.arg(
Arg::new("daemon")
.short('d')
.long("daemon")
.help("run as daemon")
)
.arg(
Arg::new("interact")
.short('i')
.long("interact")
.conflicts_with("daemon")
.help("run as interact mod")
)
.arg(
Arg::new("v")
.short('v')
.multiple_occurrences(true)
.takes_value(true)
.help("Sets the level of verbosity")
)
.subcommand(new_requestsample_cmd())
.subcommand(new_config_cmd())
.subcommand(new_multi_cmd())
.subcommand(new_task_cmd())
.subcommand(new_loop_cmd())
.subcommand(
clap::Command::new("test")
.about("controls testing features")
.version("1.3")
.author("Someone E." )
.arg(
Arg::new("debug")
.short('d')
.help("print debug information verbosely")
)
);
static ref SUBCMDS: Vec= subcommands();
}
pub fn run_app() {
let matches = CLIAPP.clone().get_matches();
if let Some(c) = matches.value_of("config") {
println!("config path is:{}", c);
set_config_file_path(c.to_string());
}
set_config(&get_config_file_path());
cmd_match(&matches);
}
pub fn run_from(args: Vec<String>) {
match clap_Command::try_get_matches_from(CLIAPP.to_owned(), args.clone()) {
Ok(matches) => {
cmd_match(&matches);
}
Err(err) => {
err.print().expect("Error writing Error");
}
};
}定义好的命令不需其他处理,框架会在系统运行时生成子命令树,用于在领域交互模式下命令提示的支持
命令解析 src/cmd/rootcmd.rs 中的 cmd_match 负责解析命令,可以把解析逻辑写在该函数中
fn cmd_match(matches: &ArgMatches) {
if let Some(ref matches) = matches.subcommand_matches("requestsample") {
if let Some(_) = matches.subcommand_matches("baidu") {
let rt = tokio::runtime::Runtime::new().unwrap();
let async_req = async {
let result = req::get_baidu().await;
println!("{:?}", result);
};
rt.block_on(async_req);
};
}
}修改交互模式的命令提示 提示符可以在src/interact/cli.rs 中定义
pub fn run() {
...
loop {
let p = format!("{}> ", "interact-rs");
rl.helper_mut().expect("No helper").colored_prompt = format!("\x1b[1;32m{}\x1b[0m", p);
...
}
...
}
下次为大家介绍一下interactcli-rs各种功能是如何实现的。
►►更多了解◄◄