7 个版本
0.1.6 | 2023 年 1 月 30 日 |
---|---|
0.1.5 | 2023 年 1 月 29 日 |
0.1.2 | 2022 年 12 月 26 日 |
#62 在 #crates
38 每月下载量
在 engineer 中使用
24KB
428 行
Engineer
Engineer 是基于 Optional
的大师级构建者。
它仅生成一个用于数据模型的 Engineer (Builder) 类。
安装
将以下内容添加为依赖项
[dependencies]
engineer = "0.1.3"
入门
use engineer::Engineer;
#[derive(Engineer)]
struct Identity {
id: usize,
username: String,
first_name: Option<String>,
last_name: Option<String>,
lang_code: Option<String>,
}
可选字段在初始化期间不是必需的。
// Option fields are set to None.
let identity = Identity::engineer(0, "immmdreza".to_string()).done();
但是,您也可以为 Option
字段设置一个值。
let identity = Identity::engineer(0, "immmdreza".to_string()) // IdentityEngineer
.first_name("Arash".to_string()) // IdentityEngineer
.last_name("Tofani".to_string()) // IdentityEngineer
.done(); // Identity
这就是基础知识,但是您可以进行一些自定义。
自定义
Engineer 结构名称
默认情况下,Engineer 结构名为 {struct}Engineer(《IdentityEngineer》对于《Identity》),但您可以更改它。
// ~~~ sniff ~~~
#[derive(Engineer)]
#[engineer(engineer_name = "IdentityBuilder")]
struct Identity {
// ~~~ sniff ~~~
}
// ~~~ sniff ~~~
let identity = Identity::engineer(0, "immmdreza".to_string()) // IdentityBuilder
.first_name("Arash".to_string()) // IdentityBuilder
.last_name("Tofani".to_string()) // IdentityBuilder
.done(); // Identity
Builder 函数名称
默认情况下,builder 函数的名称为 engineer
,但您知道吗?
// ~~~ sniff ~~~
#[derive(Engineer)]
#[engineer(builder_func = "builder")]
struct Identity {
// ~~~ sniff ~~~
}
// ~~~ sniff ~~~
let identity = Identity::builder(0, "immmdreza".to_string())
// ~~~ sniff ~~~
您想将其用作 new
函数
// ~~~ sniff ~~~
#[derive(Engineer)]
#[engineer(builder_func = "new")]
struct Identity {
// ~~~ sniff ~~~
}
// ~~~ sniff ~~~
let identity = Identity::new(0, "immmdreza".to_string())
// ~~~ sniff ~~~
这可以简化为特殊的 new
名称作为 builder 函数
#[derive(Engineer)]
#[engineer(new)]
struct Identity {
// ~~~ sniff ~~~
}
Options 的默认值
您可以设置选项字段的默认值。
如果没有设置其他值,将使用此值。
// ~~~ sniff ~~~
#[derive(Engineer)]
#[engineer(new)]
struct Identity {
// ~~~ sniff ~~~
#[engineer(default_value = r#"String::from("fa")"#)]
lang_code: Option<String>,
}
// ~~~ sniff ~~~
let identity = Identity::new(0, "immmdreza".to_string());
identity.lang_code // Some("fa")
或者,您可以使用 default
来设置 Some(Default::default)
替代 None,如果未提供其他值。
// ~~~ sniff ~~~
#[engineer(default)]
luck_number: Option<i32>, // Some(0)
// ~~~ sniff ~~~
重打字
您可以更改构建过程中请求的类型。
// ~~~ sniff ~~~
#[derive(Engineer)]
#[engineer(new)]
struct Identity {
// ~~~ sniff ~~~
#[engineer(retype(to = "impl Into<String>", re = ".into()"))]
// ^ ^
// | Requested type in public.
// |
// | How we recover to original type.
username: String,
// ~~~ sniff ~~~
}
// ~~~ sniff ~~~
let identity = Identity::new(0, "immmdreza"); // .to_string() is not needed.
// ~~~ sniff ~~~
或者,对于 str 重打字(如上面的示例),您可以使用缩写 str_retype
。
// ~~~ sniff ~~~
#[engineer(str_retype)]
username: String,
// ~~~ sniff ~~~
您还可以在全局范围内使用重打字。
#[derive(Engineer)]
#[engineer(new, retype(from = "String", to = "impl Into<String>", re = ".into()"))]
struct Identity {
// ~~~ sniff ~~~
}
或者,对于 String 重打字
#[derive(Engineer)]
#[engineer(new, str_retype)]
struct Identity {
// ~~~ sniff ~~~
}
上述两种代码都将 全部 String
字段重打字为公开 API 中的 impl Into<String>
最终结果
#[derive(Engineer)]
#[engineer(new, str_retype)]
struct Identity {
id: usize,
username: String,
first_name: String,
last_name: Option<String>,
#[engineer(str_retype, default_value = "\"fa\".to_string()")]
lang_code: Option<String>,
}
fn print_identity(ident: impl Into<Identity>) {
let ident: Identity = ident.into();
println!("{ident:#?}");
}
fn main() {
let ident = Identity::new(1, "immmdreza", "Arash").last_name("Tofani");
print_identity(ident);
// Identity {
// id: 1,
// username: "immmdreza",
// first_name: "Arash",
// last_name: Some(
// "Tofani",
// ),
// lang_code: Some(
// "fa",
// ),
// }
}
更多关于特质的介绍
这个crate有两个主要特性: Builder<T> where T: Engineer
和 Engineer
。
Engineer
特性有两个关联类型: Params
和 Builder
。
Params
是一个包含所需字段类型的元组(不是Option<_>
的字段)Builder
是Builder/Engineer类的类型。
使用 Engineer
宏,可以让您的数据类实现 Engineer
特性,并创建一个实现 Builder<T>
的Builder结构体(通常命名为 {struct_name}Engineer
- 我正在考虑重命名),其中T是您的自己的结构体。
这使您可以在这些特性周围做一些泛型操作,例如
fn build_any<E>(required: E::Params) -> E
where
E: Engineer,
{
E::build(required)
}
// Or
fn get_builder<E>(required: E::Params) -> E::Builder
where
E: Engineer,
{
E::builder(required)
}
注意,E::Params
是一个元组。
如果所有所需字段(E::Param)都实现了Default,另一个函数 build_default
将在您的结构体上可用,该函数创建一个不需要输入的默认实例。
此外,Engineer
特性有两个常量字段
- const NORMAL_FIELDS: usize;
- const OPTIONAL_FIELDS: usize;
🧀
依赖
~2MB
~42K SLoC