9 个版本

0.1.8 2021 年 8 月 22 日
0.1.7 2021 年 2 月 27 日
0.1.6 2020 年 4 月 10 日

#393数据结构

MIT 许可证

49KB
770

ibuilder

Rust Audit crates.io Docs

结构体的交互式构建器。

该软件包提供了一种交互式构造结构体(例如,结构体或枚举)的方法,提示用户进行多项选择和文本输入。

构建器为用户提供类似菜单的交互式界面,保持 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 的数值类型,boolStringcharBox<T>Vec<T>Option<T>
  • 实现 NewBuildableValue 特质的任何字段类型

使用示例

在这个示例中,数据存储在一个名为 Person 的结构体中,该结构体有 3 个字段,其中之一具有默认值。从 IBuilder 派生提供了访问 builder() 方法的能力,该方法返回一个 Builder<Person>

Figure 1 Figure 2 Figure 3
图 1:主菜单 图 2AgeRange 菜单 图 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