书接上文,上回说到如何通过interactcli-rs四步实现一个命令行程序。但是shell交互模式在有些场景下用户体验并不是很好。比如我们要连接某个服务,比如mysql或者redis这样的服务。如果每次交互都需要输入地址、端口、用户名等信息,交互起来太麻烦。通常的做法是一次性输入和连接相关的信息或者由统一配置文件进行管理,然后进入领域交互模式,所有的命令和反馈都和该领域相关。interactcli-rs通过 -i 参数实现领域交互模式。这回我们探索一下这一模式是如何实现的。

基本原理

interactcli-rs 实现领域交互模式主要是循环解析输入的每一行,通过rustyline 解析输入的每一行命令,并交由命令解析函数处理响应逻辑

当我们调用 ‘-i’ 参数的时候 实际上是执行了 interact::run() 函数(interact -> cli -> run())。

pub fn run() {let config = Config::builder().history_ignore_space(true).completion_type(CompletionType::List).output_stream(OutputStreamType::Stdout).build();let h = MyHelper {completer: get_command_completer(),highlighter: MatchingBracketHighlighter::new(),hinter: HistoryHinter {},colored_prompt: "".to_owned(),validator: MatchingBracketValidator::new(),};let mut rl = Editor::with_config(config);rl.set_helper(Some(h));if rl.load_history("/tmp/history").is_err() {println!("No previous history.");}loop {let p = format!("{}> ", "interact-rs");rl.helper_mut().expect("No helper").colored_prompt = format!("\x1b[1;32m{}\x1b[0m", p);let readline = rl.readline(&p);match readline {Ok(line) => {if line.trim_start().is_empty() {continue;}rl.add_history_entry(line.as_str());match split(line.as_str()).as_mut() {Ok(arg) => {if arg[0] == "exit" {println!("bye!");break;}arg.insert(0, "clisample".to_string());run_from(arg.to_vec())}Err(err) => {println!("{}", err)}}}Err(ReadlineError::Interrupted) => {println!("CTRL-C");break;}Err(ReadlineError::Eof) => {println!("CTRL-D");break;}Err(err) => {println!("Error: {:?}", err);break;}}}rl.append_history("/tmp/history").map_err(|err| error!("{}", err)).ok();
}

解析主逻辑

交互逻辑主要集中在 ‘loop’ 循环中,每次循环处理一次输入请求。

处理的逻辑如下:

  • 定义提示符,类似 'mysql> ',提示用户正在使用的程序

let p = format!("{}> ", "interact-rs");rl.helper_mut().expect("No helper").colored_prompt = format!("\x1b[1;32m{}\x1b[0m", p);
  • 读取输入行进行解析

  • 将输入的命令行加入到历史文件,执行过的命令可以通过上下键回放来增强用户体验。

rl.add_history_entry(line.as_str());
  • 将输入的行解析为 arg 字符串,交由 cmd::run_from 函数进行命令解析和执行

match split(line.as_str()).as_mut() {Ok(arg) => {if arg[0] == "exit" {println!("bye!");break;}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");break;}Err(ReadlineError::Eof) => {println!("CTRL-D");break;}Err(err) => {println!("Error: {:?}", err);break;}

run函数中其他代码的作用

  • 配置rustyline

在run函数最开头 定义了一个config

let config = Config::builder().history_ignore_space(true).completion_type(CompletionType::List).output_stream(OutputStreamType::Stdout).build();

这个config其实是rustyline的配置项,包括输出方式历史记录约束,输出方式等等。

MyHelper用于配置命令的autocomplete

let h = MyHelper {completer: get_command_completer(),highlighter: MatchingBracketHighlighter::new(),hinter: HistoryHinter {},colored_prompt: "".to_owned(),validator: MatchingBracketValidator::new(),
};

这里卖个关子,下期详细讲讲autocomplete的实现。

  • 配置历史文件

run函数最后,我们为程序配置了历史文件,应用于存放执行过的历史命令。这样即便程序退出,在此打开程序的时候还是可以利用以前的执行历史。

rl.append_history("/tmp/history").map_err(|err| error!("{}", err)).ok();

关于如何构建命令行的领域交互模式就说到这儿,下期详细介绍一下 autocomplete 如何实现。

- End -

►►更多了解◄◄

点击阅读原文 查看文盘Rust系列内容

文盘Rust——领域交互模式如何实现相关推荐

  1. 文盘Rust -- 领域交互模式如何实现

    作者:贾世闻 原文来源: https://tidb.net/blog/af8524fd notice"Rust is a trademark of the Mozilla Foundatio ...

  2. 文盘Rust -- 子命令提示,提高用户体验

    作者: jiashiwen 原文来源: https://tidb.net/blog/ec09d93b 文盘Rust -- 子命令提示,提高用户体验 notice"Rust is a trad ...

  3. 文盘Rust——子命令提示,提高用户体验

    上次我们聊到 CLI 的领域交互模式.在领域交互模式中,可能存在多层次的子命令.在使用过程中如果全评记忆的话,命令少还好,多了真心记不住.频繁 --help 也是个很麻烦的事情.如果每次按 'tab' ...

  4. 开发函数计算的正确姿势——使用交互模式安装依赖

    前言 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数计算 ...

  5. python的repl模式_为什么解释器的交互模式又叫 REPL

    今天着重介绍 Python 解释器的交互式模式. 什么是 REPL REPL 是 4 个单词的首字母组:Read Eval Print Loop. 它表示一个循环中,在这个循环中不断的执行: Read ...

  6. Ext学习-前后交互模式介绍

    在前后台交互模式的介绍中,实际上就是Store中Proxy相关的内容,比如Ajax提交. 所以详细的文档请参考: Ext学习-基础概念,核心思想介绍 中关于数据模型和MVC结构部分. 作者:sdjnz ...

  7. hadoop离线阶段(第十三节)数据仓库、hive简介、hive安装和hive的三种交互模式

    目录 数据仓库 数据仓库的基本概念 数据仓库的主要特征 数据仓库与数据库区别 数据仓库分层架构 数据仓库元数据管理 Hive简介 什么是Hive Hive的特点 Hive架构 Hive与Hadoop的 ...

  8. 如何盘活新零售5大线上线下交互模式?拥抱用户与收益增长

    新零售各类应用模式层出不穷,花样迭出.即使如此,细化到不同模式,普及度与效果,以及用户接受度也各有不同.新零售模式究竟有哪些?本篇,我们回归新零售模式本质,解析如何盘活5大典型线上线下交互模式,拥抱用 ...

  9. Asymptote 学习记录(1):基本的安装以及用批处理模式和交互模式绘图

    今天我安装了Asymptote,这是一款强大的数学绘画软件.在Ubuntu的软件中心便可以下载到2.15版(2013.2.17).安装完后,要运行它,只要在终端输入 asy,再按一下enter即可.可 ...

最新文章

  1. UOJ 52 元旦激光炮
  2. 汇编语言_实验九_根据材料编程
  3. git工具tig用法
  4. Python学习——02-Python基础——【9-面向对象进阶】——isinstance(obj,cls)、反射等...
  5. DataGridView里的Checkbox全选问题解决了!
  6. 40Linux组41Linux所有者42Linux所在组43Linux修改所有组
  7. python怎么实现黑客攻击英国_注意!你的隐私就是这样被黑客获取的
  8. android 静默暗转_Android静默安装
  9. php中全局变量如何设置,如何在php中声明全局变量?
  10. android按钮切换颜色,togglebutton
  11. python实现切割url得到域名、协议、主机名等各个字段
  12. 前端系列——jquery.i18n.properties前端国际化解决方案“填坑日记”
  13. 计算机联锁设备施工论文,毕业设计论文-计算机联锁设计
  14. 计算机网络技术基础第二章答案,计算机网络技术基础各章节综合练习题及答案...
  15. blender 快捷键
  16. “熵减”之下,欧瑞博填补全屋智能国产操作系统空白
  17. 【游戏开发实战】(完结)使用Unity制作水果消消乐游戏教程(九):使用UGUI显示游戏UI
  18. Word2010无法输入中文
  19. 电子邮件群发最好用的邮箱是哪个?
  20. 组态王bitset用法_宇电AI系列仪表和组态王在产品检测装置中的应用

热门文章

  1. 移动OA系统,开启办公自由便捷高效之门
  2. Win7系统配置开机自动连接宽带
  3. NOIP2008全省提高组获奖名单
  4. 【过关斩将】2021年互联网公司运维岗位面试题 -公司篇
  5. 大一化学计算机模拟实验报告,化学实验报告万能模板.doc
  6. HashiCorp Vault浅入门以及资料整理
  7. cuda c++的一些记录(3)
  8. 微信小程序(看文档写实例十)微信小程序课堂宝APP实现我的模块相关界面及逻辑
  9. 穿什么样的丝袜好看?
  10. 从JD到简历到面试到offer