Skip to content

Build from - #391

Open
BernardIgiri wants to merge 12 commits into
elastio:masterfrom
BernardIgiri:build_from
Open

Build from#391
BernardIgiri wants to merge 12 commits into
elastio:masterfrom
BernardIgiri:build_from

Conversation

@BernardIgiri

Copy link
Copy Markdown

Add build_from and build_from_clone builder methods

Closes #310

This PR is a fresh continuation of the original #313 , which I accidentally closed when rebasing my master branch. I have since transplanted my work on here:

Original PR Overview

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

  • #[builder(build_from)] – Adds a .build_from(T) / .call_from(T) method (takes T by value).
  • #[builder(build_from_clone)] – Adds a .build_from_clone(&T) / .call_from_clone(&T) method (takes &T and clones fields).

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

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

Example

Rust

#[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_clone(&jon);

assert_eq!(alice.name, "Alice");
assert_eq!(alice.age, 25);

Implementation Notes

  • The code generation engine lives in builder_gen/build_from.rs and is conditionally compiled/emitted via the experimental-build-from feature flag.
  • Integrating ItemSigConfig directly into darling::FromMeta allows native attribute parsing without structural wrapper types.
  • Each field is handled according to its member kind:
    • Named fields: Fallback to the instance data if not explicitly set in the builder state.
    • FinishFn fields: Defer to the instance data.
    • Skip fields: Drop back to Default::default().

WIP Status & Next Steps

This PR is currently open as a Draft / WIP. Before marking it ready for full review, I am working on polishing a few key items:

  • Inherit Attributes: Ensure that custom visibility (vis) and documentation (doc) passed inside #[builder(build_from(...))] are properly inherited by the generated methods.
  • Function/Method Builders: Refactor code generation to correctly support bon when applied to functions or associated methods (ensuring we invoke the execution block rather than blindly emitting a structural literal path).
  • Expanded Integration Tests: Adding test coverage for complex namespaces, turbofish paths, and custom vis/doc combinations.

@RobertasJ

Copy link
Copy Markdown

just saw this pr, got a suggestions.

build_from_clone seems like a duplicate of build_from. if you have a builder where all the fields are clone, you can just implement Clone for the struct like its done in your example, then you can call .build_from(template.clone()).

Another thing is that you should probably mark this pr as a draft pr (makes it easy to quickly see why a pr isnt merged).

also isnt your pr description kind of weird. theres no need to inherit attributes or to write weird implementation details that don't make sense without looking at the code in the first place. you also mention .call_from when you never elaborate on what it is. please make it more sense xd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: method to fill the remaining values from an instance of existing built object

2 participants