文盘Rust -- 领域交互模式如何实现
作者:京东科技 贾世闻
文盘Rust -- 领域交互模式如何实现
书接上文,上回说到如何通过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 函数最开头 定义了一个configlet 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 如何实现。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
互动玩法任务平台介绍
作者:京东科技 雷自海 一、概述 任务平台是科技内各业务方开展互动玩法的中心化平台,支撑科技内拉新、促活、交易等业务场景,包含基础任务、基于任务的通用活动玩法和业务投放能力。提供了任务玩法的创建、投放、曝光、完成等全生命周期的精细化管理,打造了基于任务的裂变、时间轴等通用活动玩法的规则化运营,致力于提升在多场景、多玩法、多频次的业务投放能力。任务中心主要战场是金融APP,目前日均500W的完成量,月UV100W,大促期间日完成量达2000W。 整体架构图如下: 任务日常投放有小金库、白条、保险、签到、养猪猪、权益中心等,并在大促、年货节等有重要流量入口,如图所示: 二、任务玩法 任务玩法是最基本的活动玩法。APP中的每个投放位在任务玩法系统中被定义为渠道,运营可以配置多个任务在某个渠道,也可以将自己的任务投放到其他渠道中,以增大流量。基础任务分为任务查询、任务接取、任务完成、领奖四个步骤,其中任务接取又分为手动接取、自动接取,领奖也分为手动领取、自动领取。 从操作上可以分为运营端、C端,运营维护任务及任务投放,C端接取任务、完成任务、领取奖励。C端整体流程上分成二个部分,用户操作层和后...
- 下一篇
深度学习调参小册
作者:京东零售 彭馨 谷歌大脑的五位深度学习大佬在 “Chinese New Year” 期间合作推出了《深度学习调参手册》,来为各位深度学习爱好者恭贺新年(我猜的),一时间好评如潮,获星过万,看来大家都是苦调参久已。难道依靠经验的调参变得“可解释”了?显然不是,而是大佬们分享自己的调参经验,内容还是挺多的,下面咱们去粗取精,希望能够获得飞升。 一、新项目指南 调参并不是开始项目的第一步,在此之前,我们要完成一些必要的基本工作,如 问题制定、数据清洗、pipeline 设置、评估指标 等确定后,花时间在模型架构和训练配置上才有意义。 1.选择模型架构 • 在进行一个新项目时,首先要尝试重用已经经过验证并有效的模型。如果要新开发,也应该选择一个完善、常用的模型架构先来开展工作,之后再去慢慢构建自己的自定义模型。 • 模型架构具有一系列的超参数,如 层数、层宽度、激活函数 等,选择架构实际上是选择具有不同超参数的模型,后面的 选择初始配置 和 提高模型性能的科学方法 主要是讲选择模型超参数的问题。 • 如果能找到一篇接近解决手头问题的论文,并将其中模型进行复现,是个很好的选择。 2.选择优...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8
- Mario游戏-低调大师作品
- Linux系统CentOS6、CentOS7手动修改IP地址
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7安装Docker,走上虚拟化容器引擎之路