当前位置: 首页 > 后端技术 > Java

文盘Rust--如何实现领域交互方式

时间:2023-04-01 23:11:45 Java

作者:京东科技贾世文文盘Rust--如何实现领域交互方式接上本书,我们分四步讲了如何实现一个命令行程序通过interactcli-rs。但是shell交互方式的用户体验在某些场景下并不是很好。比如我们要连接一个服务,比如mysql或者redis。如果每次交互都需要输入地址、端口、用户名等信息,交互起来就太麻烦了。通常的做法是一次性输入连接相关信息或者统一配置文件管理,然后进入域交互模式,所有的命令和反馈都与这个域相关。interactcli-rs通过-i参数实现域交互方式。这次我们探讨这个模型是如何实现的。interactcli-rs的基本原理是实现域交互模式,主要是循环解析每一行输入,通过rustyline解析每一行命令输入,交给命令分析函数处理响应逻辑。当我们调用'-i'参数时,它实际上执行了Addedinteract::run()函数(interact->cli->run())。pubfnrun(){letconfig=Config::builder().history_ignore_space(true).completion_type(CompletionType::List).output_stream(OutputStreamType::Stdout).build();leth=MyHelper{completer:get_command_completer(),highlighter:MatchingBracketHighlighter::new(),hinter:HistoryHinter{},colored_prompt:"".to_owned(),validator:MatchingBracketValidator::new(),};让mutrl=Editor::with_config(config);rl.set_helper(一些(h));ifrl.load_history("/tmp/history").is_err(){println!("没有以前的历史。");}loop{letp=format!("{}>","interact-rs");rl.helper_mut().expect("Nohelper").colored_prompt=format!("\x1b[1;32m{}\x1b[0m",p);让readline=rl.readline(&p);匹配readline{Ok(line)=>{如果line.trim_start().is_empty(){继续;}rl.add_history_entry(line.as_str());matchsplit(line.as_str()).as_mut(){Ok(arg)=>{ifarg[0]=="exit"{println!("bye!");休息;}arg.insert(0,"clisample".to_string());run_from(arg.to_vec())}Err(err)=>{println!("{}",err)}}}Err(ReadlineError::Interrupted)=>{println!("CTRL-C");休息;}Err(ReadlineError::Eof)=>{println!("CTRL-D");休息;}错误(错误)=>{println!(“错误:{:?}”,错误);休息;}}}RL。append_history("/tmp/history").map_err(|err|error!("{}",err)).ok();}主要逻辑分析交互逻辑主要集中在'loop'循环中,输入请求处理逻辑在每个循环中处理一次。提示定义如下,类似'mysql>',提示用户使用程序letp=format!("{}>","interact-rs");rl.helper_mut().expect("Nohelper").colored_prompt=format!("\x1b[1;32m{}\x1b[0m",p);read解析输入行并将输入的命令行添加到历史文件中。执行的命令可以通过上下键回放,提升用户体验。rl.add_history_entry(line.as_str());将输入行解析为arg字符串,传递给cmd::run_from函数进行命令解析和执行matchsplit(line.as_str()).as_mut(){Ok(arg)=>{ifarg[0]==“退出”{println!(“再见!”);休息;}arg.insert(0,"clisample".to_string());run_from(arg.to_vec())}Err(err)=>{println!("{}",err)}}解析中断,当用户执行ctrl-c或ctrl-d时,程序退出。Err(ReadlineError::Interrupted)=>{println!("CTRL-C");休息;}Err(ReadlineError::Eof)=>{println!("CTRL-D");休息;}Err(err)=>{println!("错误:{:?}",err);休息;}其他代码在run函数中的作用Configurationrustyline在run函数的开头定义了一个configletconfig=Config::builder().history_ignore_space(true).completion_type(CompletionType::List).output_stream(OutputStreamType::Stdout)。建造();这个config其实就是一个rustyline的配置项,包括输出模式历史约束,输出模式等。".to_owned(),验证器:MatchingBracketValidator::new(),};这里有一个trick,下一期会详细讲autocomplete的实现。配置历史文件运行功能最后,我们为程序配置历史文件,用于存放执行过的历史命令。这样即使程序退出了,这里打开程序的时候仍然可以使用之前的执行历史。rl.append_history("/tmp/history").map_err(|err|error!("{}",err)).ok();命令行的领域交互模式的搭建就到此为止,下一期我会详细介绍,看看autocomplete是如何实现的。