colin-kiegel / rust-derive-builder

derive builder implementation for rust structs
https://colin-kiegel.github.io/rust-derive-builder/
Apache License 2.0
1.32k stars 88 forks source link

Provides builder functions that consume ownership #296

Closed fawkesLi-lhh closed 1 year ago

fawkesLi-lhh commented 1 year ago

Most of the time, we only use builder once, but each build() will clone() members, which is inefficient and unnecessary, if we can provide a function that will consume ownership and avoid additional clones

TedDriggs commented 1 year ago

Use #[builder(pattern = "owned")] for this (docs).

loganmzz commented 1 year ago

@TedDriggs Why Clone is required for mut-based builder impl ? Regarding pseudo code in documentation, I see no relationship between chaining and ownership.

Here is my blueprint impl:

#[derive(Default)]
struct Data {
  value: usize,
}

#[derive(Default)]
struct DataBuilder {
   value: Option<usize>,
}

impl Data {
  pub fn builder() -> DataBuilder {
    DataBuilder::default()
  }
}

impl DataBuilder {
   pub fn build(&mut self) -> Data {
     let mut built = Data::default(); // Custom or generated constructor may be used to init struct
     if let Some(value) = self.value.take() {
       built.value = value;
     }
    built
   }
}
TedDriggs commented 1 year ago

Probably because that seems like it should be an owned-pattern build method at that point; it’s weird in my opinion to have the mut build method reset the builder but leave it intact.

loganmzz commented 1 year ago
  1. As far as I understand, Owned-pattern apply to setters not only to build.
  2. In this case, it's not built type but properties which have to require Clone, no ?
TedDriggs commented 1 year ago
  1. The mutable setters return a &mut of the builder, which means that the build method cannot take self without breaking chaining. Therefore, owned setters correspond with the owned signature for build.
  2. Correct