Open typedrat opened 5 months ago
You can specify a separate method for your builder to use instead of new(args: (x, y ,z))
.
You could then have your individual parameters as an alternative method that internally returns Self::new(args)
:
#[derive(Debug)]
struct Language {
name: String,
id: u32,
favourite: bool,
}
#[buildstructor::buildstructor]
impl Language {
pub fn new(args: (String, u32, bool)) -> Self {
Self {
name: args.0,
id: args.1,
favourite: args.2,
}
}
// Not `pub fn`, so it's private/hidden while the builder method will be public:
#[builder(entry = "builder", exit = "build", visibility="pub")]
fn from_args(name: String, id: u32, favourite: bool) -> Self {
Self::new((name, id, favourite))
}
}
fn main() {
let lang = Language::builder()
.name("Rust")
.id(42)
.favourite(true)
.build();
println!("{lang:#?}");
}
$ cargo run
Language {
name: "Rust",
id: 42,
favourite: true,
}
You were a bit vague on the issue and what the ideal solution would look like with buildstructor
, so I may have misunderstood 😅
UPDATE: Perhaps you were requesting the builder to abstract away the need for wrapping args as a tuple type for the generated parameter method, but internally still map as a tuple?
I have raised that feature request here (it seems to be partially supported already for collections): https://github.com/BrynCooke/buildstructor/issues/187
// NOTE: Below is just an example, not actually supported yet
#[derive(Debug)]
struct Language {
name: String,
id: u32,
favourite: bool,
}
#[buildstructor::buildstructor]
impl Language {
#[builder]
pub fn new(args: (String, u32, bool)) -> Self {
Self {
name: args.0,
id: args.1,
favourite: args.2,
}
}
}
fn main() {
// Instead of tuple wrapped single-arg `.args(("Rust", 42, true))`,
// take each as a separate arg to `.args()` instead:
let lang = Language::builder()
.args("Rust", 42, true)
.build();
println!("{lang:#?}");
}
In the linked example I have a Pair<X, Y>(X, Y)
/ Pair<String, String>
type where having the separate values as individual args might make more sense for the feature than the example I adapted above.
Currently, if you have your constructor take a tuple argument, the builder function requires a tuple. I'm using that to represent multiple values that don't make sense to set independently, but it would be a little bit cleaner if the methods on the builder took multiple arguments, one for each member of the tuple, rather than a tuple itself.