-
Notifications
You must be signed in to change notification settings - Fork 16
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
Enum Support #23
Comments
I haven't seen a need for enum builders on my experience. I usually write enums with tuple-like variants that have struct types embedded in them: enum Foo {
A(AStruct)
B(BStruct)
}
struct AStruct { field: String, field2: u32 }
struct BStruct { field bool } It makes it possible to extract that struct from the enum and process it outside of a enum Foo {
A { field: String, field2: u32 },
B { field: bool }
} I'd like to know more about your use case and how builder for enum would solve it. From my side, I can tell that I have another good proc macro currently in a private repo that I may potentially open-source (maybe as part of Here is the snippet of its documentation: Derives various
Having such a macro allows you to avoid building enums directly. Instead you'd define enums as pure sum types, which you can create out of structs that derive builders. For example: use bon::builder;
#[derive(Sum)]
enum Foo {
A(A),
B(B),
}
#[builder]
struct A {}
#[builder]
struct B {}
// Create the enum:
let enum_value: Foo = A::builder().build().into();
let a: A = enum_value.unwrap_a();
let enum_value: Foo = B::builder().build().into();
let b: B = enum_value.unwrap_b(); |
I'd suggest discussing alternative simpler approaches first like the one above with generating Drawing some inspiration from this PR into For example, there were some good points raised about naming of methods. Enums usually have methods named after variants to implement getters like |
While I typically prefer using structs for clarity when dealing with more than three fields, I've found that for simpler cases with one to three fields, directly using enum variants is often sufficient. My current project involves building an expression tree with
For instance, relying on methods like
I'd probably lean towards having an PS - Didn't see your comment before opening the PR |
That Another comment about your use case. Did you consider defining builders for your enums via methods? For example: use bon::bon;
enum Expression {
Number(u32),
Binary {
op: String,
left: Box<Self>,
right: Box<Self>,
}
}
#[bon]
impl Expression {
#[builder(finish_fn = build)]
fn binary(
op: String,
#[builder(into)]
left: Box<Self>,
#[builder(into)]
right: Box<Self>,
) -> Self {
Self::Binary { op, left, right }
}
}
Expression::binary()
.op("==")
.left(Expression::Number(1))
.right(Expression::Number(3))
.build(); It is a bit more code to write, but it generates the builder that you'd like. This will let you have a builder for your enum without the need to go the long-long route of designing and implementing builders for enums in Basically defining |
You're right, I didn't seem think of that. It actually solves the problem. I'll close this then |
I'm interested in using your tool but it currently lacks support for Rust enums. I propose extending the macro to handle enums as well.
For unit enums, the macro could either ignore them or generate a dummy function. For example
For unnamed enums, I'm unsure whether generating no code or implementing a default 'from' function for each variant is the best approach. For example
For named enums, we create a builder struct, generate builder methods for each field, and modify the
finish_fn
to return the enum variant instead of the builder struct. Additionally, astart_fn
would be generated to create a new builder instance from the enum. SoThe text was updated successfully, but these errors were encountered: