9 个版本
0.1.8 | 2021 年 8 月 22 日 |
---|---|
0.1.7 | 2021 年 2 月 27 日 |
0.1.6 | 2020 年 4 月 10 日 |
#393 在 数据结构
49KB
770 行
ibuilder
结构体的交互式构建器。
该软件包提供了一种交互式构造结构体(例如,结构体或枚举)的方法,提示用户进行多项选择和文本输入。
构建器为用户提供类似菜单的交互式界面,保持 UI 抽象和 Rust 类型安全。
理由
当构建一个交互式应用程序(例如,Telegram 机器人或控制台应用程序)时,如果不编写大量处理解析和验证输入的逻辑代码,就很难创建出一个不错的界面。
此软件包提供了一个有用的抽象,允许数据与用户界面之间的简单连接。只需派生一个定义您数据的结构体(或枚举),即可获得用于构建 UI 的安全界面。
derive API 受到优秀的 structopt
软件包的启发。
API 概述
此软件包的 API 非常简单
- 从
IBuilder
派生一个结构体(或枚举),包括它所依赖的所有结构体/枚举; - 调用
builder()
方法(来自Buildable
特性)以获取Builder<T>
的实例; - 在构建器上调用
get_options()
,以获取包含要向用户显示的消息、可能的 选择 列表(即要按的按钮)以及输入文本的可能性(即文本框)的对象; - 在构建器上调用
to_node()
,以获取一个树状结构,其中包含构建器的状态,突出显示仍需执行操作的字段; - 您可以选择如何向用户显示选项,当用户做出决定时,在构建器上调用
choose(input)
。如果选择有效,则将选择应用于结构体的状态,否则返回错误; - 当状态完成(所有必需字段都已存在)时,列表中会出现一个新的选项:完成。如果用户选择它,
choose
将返回一个T
的实例。
可以在 这里 找到 ibuilder
属性的所有可能选项列表。
支持的功能
- 从具有命名字段的结构体(或具有一个未命名字段的
struct Foo(i64)
)派生 - 枚举(也具有带有字段的变体,但只有一个未命名的)
- 字段和枚举的默认值
- 字段、结构体、枚举和变体的自定义消息提示
- 重命名字段、结构体和变体以获得更好的选项外观
- 隐藏字段(仅从默认值获取值)
- 嵌套结构(即自定义类型)
- 支持的字段类型:所有 Rust 的数值类型,
bool
,String
,char
,Box<T>
,Vec<T>
和Option<T>
- 实现
NewBuildableValue
特质的任何字段类型
使用示例
在这个示例中,数据存储在一个名为 Person
的结构体中,该结构体有 3 个字段,其中之一具有默认值。从 IBuilder
派生提供了访问 builder()
方法的能力,该方法返回一个 Builder<Person>
。
图 1:主菜单 | 图 2:AgeRange 菜单 |
图 3:再次是主菜单 |
use ibuilder::*;
#[derive(IBuilder)]
pub struct Person {
#[ibuilder(rename = "full name")]
full_name: String,
age: AgeRange,
#[ibuilder(default = 2, rename = "number of hands")]
num_hands: u64,
}
#[derive(IBuilder, Debug, Eq, PartialEq)]
#[ibuilder(prompt = "How old are you?")]
pub enum AgeRange {
#[ibuilder(rename = "Less than 13 years old")]
Child,
#[ibuilder(rename = "From 13 to 19 years old")]
Teen,
#[ibuilder(rename = "20 years or more")]
Adult,
#[ibuilder(rename = "I don't want to tell")]
Unknown,
}
let mut builder = Person::builder();
// * figure 1 *
let options = builder.get_options(); // main menu: select the field to edit
builder.choose(Input::choice("age")).unwrap(); // select the field
// * figure 2 *
let options = builder.get_options(); // age menu
builder.choose(Input::choice("Adult")).unwrap(); // insert the value
let options = builder.get_options(); // back to the main menu
builder.choose(Input::choice("full_name")).unwrap(); // select the field
let options = builder.get_options(); // full_name menu
assert!(options.text_input); // for inserting the string value
builder.choose(Input::text("edomora97")).unwrap(); // insert the value
// * figure 3 *
assert!(builder.is_done());
let options = builder.get_options(); // main menu again, but the "Done" option is available
// chose the "Done" option, the return value is Ok(Some(Person))
let value = builder.choose(Input::Choice(FINALIZE_ID.to_string())).unwrap().unwrap();
assert_eq!(value.full_name, "edomora97");
assert_eq!(value.age, AgeRange::Adult);
assert_eq!(value.num_hands, 2);
许可证:MIT
依赖关系
~61–285KB