seokminhong / builder-pattern Goto Github PK
View Code? Open in Web Editor NEWA derivable macro for declaring a builder pattern.
Home Page: https://crates.io/crates/builder-pattern
License: MIT License
A derivable macro for declaring a builder pattern.
Home Page: https://crates.io/crates/builder-pattern
License: MIT License
#[derive(Build)]
struct Test {
a: i32,
#[setter(into)]
b: i32,
}
will generate
impl<T2> TestBuilder<(), T2> {
fn a(self, value: i32) -> TestBuilder<i32, T2> {
TestBuilder {
a: Some(value),
b: self.b,
}
}
}
impl <T1> TestBuilder<T1, ()> {
fn b<IntoValue: Into<i32>>(self, value: IntoValue) -> TestBuilder<T1, i32> {
TestBuilder {
a: self.a,
b: Some(value.into()),
}
}
}
for fields.
When the required fields are not properly provided, the compiler cannot deduce the build
function. In that time, the compile error message would be like this:
no method named `build` found for struct `TestBuilder<...>` in the current scope
It will be helpful that the compiler suggests missing required fields like this:
Cannot build `Test` because following fields are required:
- name: String
- age: u8
It may be easily implemented if the Specialization feature is implemented, but the feature is not stable.
In the following code:
#[derive(Builder)]
struct Test {
#[default(0, skip)]
a: i32,
}
, no setter function will be generated for Test::a
. It will just set as the default value.
I cannot get async_trait and builder-pattern to play nice together.
My test (assume MyAsyncTrait exists):
#[derive(Builder)]
pub struct MyStruct {
a: SomeStructA,
b_provider: Box<dyn MyAsyncTrait>,
}
It complains that MyAsyncTrait cannot be made into an object. My guess is that either the double-code generation breaks something OR that builder-pattern would need to place the #[async_trait]
in its generated code too.
This is currently blocking me from using the builder pattern.
If this is too hard to implement, Rust aims to support a first version of stable async traits (not via library) from 1.74, which should land in July. Then this might be resolved. What do you think?
It will make a setter public even though the field is declared private.
mod test {
#[derive(Builder)]
pub struct Test {
a: i32,
}
}
let t1 = test::Test::new()
.a(5) // Cannot access `a` because it is private
.build();
mod test {
#[derive(Builder)]
pub struct Test {
#[public]
a: i32,
}
}
let t1 = test::Test::new()
.a(5) // It works
.build();
struct PrivateTest<'a, 'b: 'a, T: Sized, U>
where
U: Clone,
{
pub a: T,
pub b: std::borrow::Cow<'a, U>,
#[default(String::from(""))]
pub c: String,
pub d: &'b &'static i32,
}
The above code should be parsed.
extern crate builder_pattern;
use builder_pattern::Builder;
#[derive(Builder)]
pub struct Whatever {
#[default(|i| -i)]
#[hidden]
bar: fn(i8) -> i8,
}
Error:
= help: message: not implemented: `hidden` attribute requires `default` attribute.
#[derive(Builder)]
struct Test {
#[setter(validator: to_absolute)]
positive: i32,
}
fn to_absolute(val: i32) -> Result<i32, ()> {
if val > 0 {
Ok(val)
} else if val < 0 {
Ok(-val)
} else {
Err(())
}
}
will generate
impl TestBuilder<()> {
fn positive(value: i32) -> std::result::Result<TestBuilder<i32>, ()> {
match to_absolute(value) {
Ok(v) => TestBuilder {
a: Some(v),
},
Err => Err(()),
}
}
}
for the field.
Hello good night, I would like to know if the lib is being constantly updated or is it abandoned
To make setter for lazy-evaluating, add the attribute for declaring setter functions take a closure instead of values directly. The closure will be evaluate when the structure is built.
Example usage:
#[derive(Builder)]
struct Foo {
pub bar: i32,
#[lazy] // Provides lazy and direct setter both. The lazy setter will be named `baz_lazy`.
pub baz: i32,
#[lazy_only] // Only provide lazy setter. Its name will be just `qux`.
pub qux: i32
}
let foo1_builder = Foo::new()
.bar(3)
.baz_lazy(|| some_heavy_task())
.qux(|| another_heavy_task());
let foo2_builder = Foo::new()
.bar(2)
.baz(some_heavy_task()) // `baz` is evaluated here.
.qux(|| another_heavy_task());
let foo1 = foo1_builder.build(); // `baz` and `qux` are evaluated here.
let foo2 = foo2_builder.build(); // `qux` is evaluated here.
Also, default
attribute can be lazy too.
#[derive(Builder)]
struct Foo {
#[default_lazy(|| some_heavy_task())]
pub bar: i32,
}
let foo1_builder = Foo::new();
let foo1 = foo1_builder.build(); // `bar` is evaluated here.
let foo2_builder = Foo::new().bar(another_heavy_task()); // `bar` is evaluated here.
let foo2 = foo2_builder.build();
Given a struct like this:
#[derive(Debug, Builder)]
pub struct QueryParameters {
pub table_name: String,
#[default(Option::None)]
pub index_name: Option<String>,
#[default(Option::None)]
pub key_condition_expression: Option<String>,
pub expression_attribute_values: Vec<(String, AttributeValue)>,
}
I would like to generate like this:
QueryParameters::new()
.table_name("table")
.add_expression_attribute_values(("string".to_string(), AttributeValue::S("attribute")))
.add_expression_attribute_values(("secondString".to_string(), AttributeValue::S("second attribute")))
.build();
So when calling "new" the expression_attribute_values are initialized, and then I can call the builder method however many times I want and it will add to the existing Vec.
The same could also be applied to HashMap and other iterables.
Similar to what lombok provides for java devs:
https://projectlombok.org/features/Builder#singular
I checked the documentation but couldn't find a way to do this with the current version of the library.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.