Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map result of build function #162

Closed
Luro02 opened this issue Mar 8, 2020 · 4 comments
Closed

Map result of build function #162

Luro02 opened this issue Mar 8, 2020 · 4 comments

Comments

@Luro02
Copy link
Contributor

Luro02 commented Mar 8, 2020

I quite frequently find myself writing code like this

fn do_something() -> Result<(), Error> {
    builder::default()
        .build()
        .map_err(Error::builder)?;
}

It would be nice if I could specify this as an attribute (so I do not have to map the result myself)

#[builder(build_fn(map_err(fn = "Error::custom", returns = "path::to::retun::type")))]
// or
#[builder(build_fn(map_err(fn = "|e| Error::custom(e)", returns = "path::to::retun::type")))]

Closures accept both Error::custom (path to a function) and |e| Error::custom(e), which would mean one could simply do

tokens.append_all(quote! { .map_err(#closure) });
// or something like that

The function would have to have the signature of

fn(String) -> #returns;
// or maybe
fn(&'static str) -> #returns;

which could be verified with an assertion in the output like this

// fn x(_: &str) -> usize { 0 }

quote_spanned! { attribute_span => {
    struct _AssertClosure<T: Fn(String) -> #returns>(T);
    _AssertClosure(#closure);
}};

Allowing this has several benefits:

  • A library author can have a single error type for all functions that return a Result (not a mixture of Error and String).
  • The build function would no longer need to allocate a String (a proc-macro should be able to produce &'static str?)
  • and this library could become true no_std, without depending on alloc?
@TedDriggs
Copy link
Collaborator

This feels like it's related to #60; rather than encouraging people to parse the string error, we should have the crate expose a way to produce a more structured error and allow people to map over that.

@TedDriggs
Copy link
Collaborator

We're closing in on a solution to this in #194. The code would be:

#[derive(Builder)]
#[builder(build_fn(error = "YourError"))]
struct YourStruct {}

impl From<derive_builder::UninitializedFieldError> for YourError {
    // ... details elided
}

@Luro02, can you confirm if that would meet your needs?

@Luro02
Copy link
Contributor Author

Luro02 commented Jan 19, 2021

@TedDriggs Looks good 👍

@TedDriggs
Copy link
Collaborator

Fixed in #194

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants