colin-kiegel / rust-derive-builder

derive builder implementation for rust structs
https://colin-kiegel.github.io/rust-derive-builder/
Apache License 2.0
1.32k stars 88 forks source link

Potential to allow for arguments in custom validator function #301

Closed rickymagner closed 10 months ago

rickymagner commented 10 months ago

Hi, thanks for this package which looks great. I was wondering if it might be possible either currently or in the future to use the validation function with optional user inputs?

For example, currently you would use:

#[builder(build_fn(validate = "path::to::fn"))]

to have a fixed function decide whether the resulting object should be built based on the user inputs. It would be great to have some option to write e.g.

#[builder(build_fn(validate = "path::to::fn", validate_opts = my_object))]

where my_object is a struct holding some user-configurable options to control how strict the validate fn is about validation. This struct could be passed as the first arg to fn when performing validation.

TedDriggs commented 10 months ago

This could be done with a custom method in your own impl block on the builder, so it’s not something the crate needs to provide internally.

rickymagner commented 10 months ago

Thanks, could you elaborate a little bit more on how one might go about writing this in the impl block? Even just some pseudocode sketch would be helpful. I'm still not fully familiar with the package.

TedDriggs commented 10 months ago
#[derive(Builder)]
#[builder(build_fn(private))]
struct Example {}

impl ExampleBuilder {
    pub fn build_with_validation(&self, validator_opts: ValidatorOptions) -> Result<Example, ExampleBuilderError> {
        // do your validation here, returning `Err` if it fails
        self.build()
    }
}

The generated build function is made private, so it can't be called outside the module. Then you add your own impl block to the builder (note that it's on ExampleBuilder, not Example) which does your custom validation and then calls the generated self.build.

rickymagner commented 10 months ago

This is helpful, thank you!