Giter Club home page Giter Club logo

builder-pattern's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

builder-pattern's Issues

Implement an attribute to use `Into` traits for fields

Example

#[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.

Provide meaningful compile error when build fails

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.

Enable to skip making setter function

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.

async_trait incompatible with builder-pattern

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?

`public` attribute

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();

Fix parse errors for lifetype bounds

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.

inadequate error for unsupported(?) default value tokens

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.

Implement a validation attribute for fields

#[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.

lib activity

Hello good night, I would like to know if the lib is being constantly updated or is it abandoned

Add attributes for lazy evaluation

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();

Allow adding independent values to a Vec/HashMap etc.

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.