idanarye/rust-typed-builder

Ensuring that at least one of a set of fields are set

Opened this issue · 5 comments

It would be great if I could say something along the lines of:

#[derive(TypedBuilder)]
struct Foo {
    #[group(a)]
    #[default]
    bar: Option<String>,
    #[group(a)]
    #[default]
    baz: Option<String>,
    #[default]
    bat: Option<String>,
}

Made up the syntax, but basically some way to signal "one or both of bar/baz must be provided".

I don't think the Rust type system is flexible enough to allow this...

Actually... I was thinking about using marker traits, which are not stable yet, but instead I can use empty fields. Just set a field for each group and override its type when any member of the group is assigned.

I recommend stealing from #[cfg], for both optimal flexibility and familiarity.

Something like this, on the struct (not on the field any more):

#[builder(group = "a", required, any("bar", all("baz", not("quux"))))]

This would define a named group “a” (the name is for documentation, and may also be used in other places that accept a field or group, such as field dependencies which I’m about to create an issue about). In this case the group is also then declared to be required before build() can be called.

Recently started using this crate and quickly ran into a scenario that required something like this.

Is anyone working on this? If not, is anyone able and willing to provide guidance on getting this implemented?

See #14 and my algorithm https://codeberg.org/mo8it/sus-impls

The macro has to use the algorithm to generate implementations