-
Notifications
You must be signed in to change notification settings - Fork 89
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
Feature/macros ono dot one #32
Conversation
Note: Since all tests run inside of a sub-crate right now, we currently don't have doc-tests anymore. :-/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice! Looks like the original tests still work :)
I would like to change the attribute names to more explicitly show they are for derive-builder – but I also really want to land this! So I'm okay with not changing them right now.
|
||
And this is how it works: | ||
|
||
```rust | ||
#[macro_use] extern crate custom_derive; | ||
#![feature(proc_macro)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't need this no more!
} | ||
|
||
#[derive(Default, Debug)] | ||
pub struct OptionsBuilder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heh, this code looks like a great indicator for a new "indirect builder" setting!
(Indirect builders are the "original" builder pattern using a struct with the same fields but all are optional.)
} | ||
} | ||
|
||
impl OptionsBuilder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seriously, the first bunch of methods can be derived, incl. the warn!
output.
Also just as a warning, every tooling project I work on at some point ends up dogfooding itself :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it felt like irony to write so much builder boilerplate in this crate. LOL. ^^
But how could we bootstrap if derive_builder
depends on derive_builder
? Shall we depend on the latest previously published version? But if that depends on the version before .. well .. people will notice strange dependency chains in their projects. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's just adopt the new rustbuild build system! It can easily download a "stage0" snapshot of derive-builder before building derive-builder stage1, and then build-derive again with the stage1 build to finally get a stage2 version we can work with.
_ => {} | ||
} | ||
} | ||
debug!("Ignoring attribute."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would not use these attribute names, as they live in a global namespace and "getters" and "setters" is too generic (we just had that in diesel/rocket with "options"). How about something like #[builder_options(setters(pattern = mutable, private = true), getter(public = true)]
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm, I see what you mean.
I am open to a discussion. However I think we should try to keep it short, since the purpose of this crate is to avoid boiler plate. One of the next logical steps IMO would be to add options per struct field. I.e. prefix, pattern, visibility, etc. could all be changed on a per-field level. At least it should be possible to ignore individual fields - and if we introduce that, we can also introduce overwriting all the other options.
#[derive(Builder)]
#[builder_options(setters(pattern = mutable, private = true), getters(public = true)]
struct Foo {
foo: u32,
#[builder_options(setter(prefix = with, pattern = immutable, private = false), getter(prefix = has, public = false)]
bar: u32
}
vs.
#[derive(Builder)]
#[setters(mutable, private), getters(public)]
struct Foo {
foo: u32,
#[setter(prefix = with, immutable, public), getter(prefix = has, private)]
bar: u32
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good points, and I think you are right: Let's keep it concise, i.e. call the attributes (s|g)etter(s?)
.
Another point: Do you think it'd be nicer to have setter and getter options defined in the same , or in two separate attributes?
_ => { | ||
panic!("Unknown option {:?}", ident) | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like there should be an idiomatic solution to parsing syn attributes to structs. Maybe another derive crate? A small serde plugin for (de)serializing things to/from rust attributes? The possibilities are infinite! :D
#[derive(Deserialize)] struct Options { setters: SetterOptions, /* … */ }
#[derive(Deserialize)] struct GetterOptions { pattern: SetterPattern, public: bool, private: bool }
#[derive(Deserialize)] enum SetterPattern { Owned, Mutable, Immutable }
// …
let attr: syn::Attribute = attr;
let opt: Options = parse_attribute!(builder_options);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this kind of separation is, what I was looking for. :-)
Sounds interesting, I'll have a look at serde. Never used it before, but since everyone is talking about that's probably an education gap I should close anyway. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes we definitely need a better approach. I am tracking this in dtolnay/syn#25.
} | ||
|
||
fn parse_getters_options(&mut self, nested: &[syn::NestedMetaItem]) -> &mut Self { | ||
panic!("TODO: parse getter options -> {:?}", nested); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably s/panic!/unimplemented!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually in published code I would like to get rid of these unimplemented functions. But generally you are right. :-)
@colin-kiegel what about the doc tests in lib.rs? They can still do their thing, right? |
@killercup It looks like having |
I updated the documentation - we can still change the syntax however. |
was fixed by migrating to macros 1.1 this only adds the testcase
@colin-kiegel I suggest we merge this and iterate on it in further PRs |
ok, done. :-) Btw: I've already started some refactoring to allow for field-based options. I'll try to wrap it up in a new PR later this evening. |
Nice, I'm looking forward to that.I'll also try to look into the builder varaints/typed builders again.
… Am 19.01.2017 um 13:13 schrieb Colin Kiegel ***@***.***>:
ok, done. :-)
Btw: I've already started some refactoring to allow for field-based options. I'll try to wrap it up in a new PR later this evening.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
@killercup: Here is the current state of the
macros_one_dot_one
branch. I continued the work of @badboy from #28.I added backward compatibility to our existing feature:
I also introduced new features:
#[setters(immutable)]
#[setters(private)]
RUST_LOG=derive_builder=trace cargo test
Things I am not yet quite happy with
src/options.rs
. I wonder if there is a cleaner approach to it.Any suggestions are welcome.