-
Notifications
You must be signed in to change notification settings - Fork 52
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
Ideas about using closures #66
Comments
Why go an extra mile just to decrease usability? The builder is already Also, I disagree with your claim that:
Consider this: let conf = Config::builder()
.foo(some_string.parse()?)
.bar("Rust <3".into())
.build() Converting this to your closure style won't work: let conf = Config::build(|builder| builder
.foo("some_user_string".parse()?) // can't just ? from a any old closure...
.bar("Rust <3".into())
); We'd have to add another method: let conf = Config::try_build(|builder| Ok(builder
.foo("some_user_string".parse()?)
.bar("Rust <3".into())
))?; This is already starting to get a little weird, but it gets worse. That code won't type-check. The reason is that for obvious reasons we want to make match result {
Ok(ok) => ok,
Err(err) => {
return Err(err);
}
} But it's actually more like match result {
Ok(ok) => ok,
Err(err) => {
return Err(err.into());
}
} Noticed the
But... Rust doesn't know what So, we'd have to do something like this: let conf = Config::try_build(|builder| Ok::<_, ParseIntError>(builder
.foo("some_user_string".parse()?)
.bar("Rust <3".into())
))?; At this point, would you not agree that it's at least a little bit "worse syntactically"? |
I didn't really consider the case where we might want to |
I'll preface this by saying that my idea is a huge breaking change, and I'm more interested to hear feedback on whether this would even work.
Currently,
typed-builder
requires the programmer calls.build()
at the end, and also exposes*Builder
types that can be created and thrown around anywhere. This isn't necessarily a bad thing, but semantically it doesn't make sense to ever allow a builder type to not be built to completion, which is possible by just not calling.build()
.I propose that we use a closure instead, which I would argue isn't any worse syntactically:
This way, we no longer have to call
.build()
manually; whatever is returned by the closure is what gets built. We can also enforce that the only way (in the public API) to get a*Builder
is getting passed one as the closure argument, which can never be taken out of context and must get used. This would also require not implementingClone
.Thoughts? Is there a reason it's not designed like this?
The text was updated successfully, but these errors were encountered: