bon icon indicating copy to clipboard operation
bon copied to clipboard

Adding support for `build_from` and `build_from_clone` builder methods.

Open BernardIgiri opened this issue 6 months ago • 0 comments

Add build_from and build_from_clone builder methods

Closes #310

This PR adds support for two new optional top-level builder attributes:

  • #[builder(build_from)] – Adds a .build_from(&T) method
  • #[builder(build_from_clone)] – Adds a .build_from_clone(T) method

These methods allow partially configured builders to fill in missing fields from an existing instance of the target type (T) before finalizing the build. This is useful when:

  • You want to override only a few fields but reuse most of the existing data.
  • You're working with types that aren't Default, making field reuse non-trivial.

Example

#[derive(Builder, Clone)]
#[builder(build_from, build_from_clone)]
struct User {
    name: String,
    age: u8,
}

let jon = User::builder().name("Jon".into()).age(25).build();
let alice = User::builder().name("Alice".into()).build_from(&jon);
assert_eq!(alice.name, "Alice");
assert_eq!(alice.age, 25);

Implementation notes

  • The new code lives in builder_gen/build_from.rs and is only emitted if the attributes are enabled.

  • Each field is handled according to its member kind:

    • Named fields fallback to from.field.clone() if not explicitly set.
    • FinishFn fields always defer to from.field.clone().
    • Skip fields use Default::default().
  • Integration tests verify both methods.

Next steps

  • Reference docs have been stubbed in src/__/ide.rs; we may want to flesh out the corresponding links on the site.

@Veetaha This implements the optional build_from and build_from_clone methods discussed in #310 — feedback welcome!

BernardIgiri avatar Jul 03 '25 06:07 BernardIgiri