32 个版本
0.20.0 | 2024年2月14日 |
---|---|
0.13.0 | 2024年1月22日 |
0.12.0 | 2022年11月28日 |
0.11.2 | 2022年4月20日 |
0.2.1 | 2016年9月24日 |
在 Rust 模式 中排名 11
每月下载量 1,397,726
在 1,923 个 包(715 个直接)中使用
38KB
构建器模式派生
Rust 宏,用于自动为任意结构体实现 构建器模式。一个简单的 #[derive(Builder)]
将为您生成一个 FooBuilder
,其中包含所有设置方法和一个构建方法。
工作原理
#[macro_use]
extern crate derive_builder;
#[derive(Default, Builder, Debug)]
#[builder(setter(into))]
struct Channel {
token: i32,
special_info: i32,
// .. a whole bunch of other fields ..
}
fn main() {
// builder pattern, go, go, go!...
let ch = ChannelBuilder::default()
.special_info(42u8)
.token(19124)
.build()
.unwrap();
println!("{:?}", ch);
}
请注意,我们没有编写任何 ChannelBuilder
的定义或实现。相反,derive_builder
包在编译时生成必要的代码,作用在 #[derive(Builder)]
上。
这是您不需要编写的生成的样板代码。:-)
#[derive(Clone, Default)]
struct ChannelBuilder {
token: Option<i32>,
special_info: Option<i32>,
}
#[allow(dead_code)]
impl ChannelBuilder {
pub fn token<VALUE: Into<i32>>(&mut self, value: VALUE) -> &mut Self {
let mut new = self;
new.token = Some(value.into());
new
}
pub fn special_info<VALUE: Into<i32>>(&mut self, value: VALUE) -> &mut Self {
let mut new = self;
new.special_info = Some(value.into());
new
}
fn build(
&self,
) -> Result<Channel, ChannelBuilderError> {
Ok(Channel {
id: match self.id {
Some(ref value) => Clone::clone(value),
None => {
return Err(
Into::into(
::derive_builder::UninitializedFieldError::from("id"),
),
)
}
},
token: match self.token {
Some(ref value) => Clone::clone(value),
None => {
return Err(
Into::into(
::derive_builder::UninitializedFieldError::from("token"),
),
)
}
},
special_info: match self.special_info {
Some(ref value) => Clone::clone(value),
None => {
return Err(
Into::into(
::derive_builder::UninitializedFieldError::from("special_info"),
),
)
}
},
})
}
}
注意:此内容已编辑以增强可读性。生成的代码不假设 Into
等特质在作用域中,并使用完整路径来访问它们。
开始使用
只需三个步骤即可
- 将
derive_builder
添加到您的Cargo.toml
中,手动或使用 cargo-edit
cargoadd derive_builder
- 添加
use derive_builder::Builder;
- 使用以下方式对结构体进行注释:
#[derive(Builder)]
使用方法和功能
- 链式调用:由于默认情况下setter调用会消耗并返回
&mut self
,因此setter调用可以链式调用。 - 构建器模式:您可以通过在结构体(或字段)前添加
#[builder(pattern = "owned")]
或#[builder(pattern = "immutable")]
来选择其他构建器模式。 - 可扩展性:您仍然可以为自己的构建器结构体定义实现并定义额外的方法。只需确保它们的名称与setter和build方法不同即可。
- 文档和属性:可以通过简单地注释相应的字段来注释setter方法。同样,
#[cfg(...)]
和#[allow(...)]
属性也应用于setter方法。 - 隐藏字段:您可以通过在每个字段上单独使用
#[builder(setter(skip))]
来跳过setter。 - setter可见性:您可以通过在结构体前添加
#[builder(private)]
来选择私有setter。 - setter类型转换:使用
#[builder(setter(into))]
,setter方法将针对输入类型进行泛型化 - 您可以为此字段类型提供实现Into
特质的每个参数。 - 设置器条带选项:使用
#[builder(setter(strip_option))]
,设置器方法将以T
作为类型参数,为类型为Option<T>
的字段。 - 集合设置器:将
#[builder(setter(each(name = "method_name")))]
添加到实现Default
和Extend
的字段,将为该字段生成一个设置器,该设置器会将项目添加到构建器的集合中。这些设置器还可以针对Into<T>
特质进行泛型化,如下所示:#[builder(setter(each(name = "foo", into)))]
。 - 构建器字段可见性:您可以使用
#[builder(field(private))]
或..(public)
来设置构建器字段的可见性。 - 泛型结构体:也受到支持,但如果您还启用了设置器类型转换,则不得使用名为
VALUE
的类型参数。 - 默认值:您可以使用
#[builder(default)]
来委托给Default
实现或通过= ".."
传递任何显式值。这在结构体和字段级别都适用。 - 预构建验证:您可以使用
#[builder(build_fn(validate = "path::to::fn"))]
在目标结构体生成之前添加自己的验证。 - 抑制构建方法:您可以使用
#[builder(build_fn(skip))]
来禁用自动实现的构建方法并提供自己的实现。 - 自定义构建方法错误类型:您可以使用
#[builder(build_fn(error = "path::to::Error"))]
使构建器返回您选择的错误类型。默认情况下,宏将生成与构建器一起的错误类型。 - 构建器派生:您可以使用
#[builder(derive(Trait1, Trait2, ...))]
来使构建器派生额外的特征。所有构建器都派生了Default
和Clone
,因此您不应在此属性中声明这些。 - 透传属性:使用
#[builder_struct_attr(...)]
、#[builder_impl_attr(...)]
、#[builder_field_attr(...)]
和#[builder_setter_attr(...)]
来声明将被添加到生成的构建器相关部分的属性。 - 支持 no_std:只需在您的结构体中添加
#[builder(no_std)]
,使用功能alloc
,并将extern crate alloc
添加到您的 crate 中。 - 不支持 alloc 和 no_std:不使用
alloc
功能,然后在您的结构体中添加#[builder(no_std, build_fn(error(validation_error = false)))]
或#[builder(no_std, build_fn(error = "path::to::Error"))]
。 - 重命名和重新导出支持:使用
#[builder(crate = "...")]
设置derive_builder
的根。如果您想在Cargo.toml
中重命名derive_builder
或您的 crate 正在重新导出derive_builder::Builder
并且需要生成的代码不直接引用derive_builder
crate,这将非常有用。
有关更多信息示例,请参阅我们的 文档。
注意事项
- 元组结构和单元结构不支持,因为它们没有字段名。我们不打算支持它们。
- 在定义泛型结构体时,不能将
VALUE
用作泛型参数,因为所有设置器都在使用它。
文档
所有功能的详细说明和故障排除技巧。您还可以找到关于不同构建模式的讨论。
变更日志
是的,我们保留变更日志。
许可
许可方式如下
- Apache许可证版本2.0,(LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
贡献
除非您明确表示,否则您提交的任何贡献,根据Apache-2.0许可证的定义,有意包含在作品中,均将根据上述条款双重许可,不附加任何其他条款或条件。
依赖项
~0.8–1.2MB
~27K SLoC