derive_builder_apply_to 0.1.0

A procedural macro for generating apply_to methods for builder patterns
Documentation
  • Coverage
  • 100%
    2 out of 2 items documented1 out of 1 items with examples
  • Size
  • Source code size: 8.45 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 273.29 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 4s Average build duration of successful builds.
  • all releases: 4s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • cranium

derive-builder-apply-to

A procedural macro for generating apply_to methods for builder patterns, designed to work seamlessly with the derive_builder crate.

Overview

The derive_builder crate is fantastic for creating new objects using the builder pattern. However, builders are typically used only for construction - once you call .build(), the builder is consumed.

This crate extends that functionality by allowing you to use builders to modify existing structs. Instead of building new objects, you can selectively update existing ones with only the fields you want to change.

This is especially useful for:

  • Partial updates in APIs (PATCH operations)
  • Configuration merging
  • Applying user preferences to default settings
  • Any scenario where you want to modify only specific fields

The ApplyTo derive macro generates an apply_to method on builder structs that:

  • Applies only the fields that have been explicitly set (non-None values)
  • Returns a boolean indicating whether any changes were made
  • Avoids unnecessary writes when values haven't changed

Usage

Add this to your Cargo.toml:

[dependencies]
derive_builder = "0.20"
derive-builder-apply-to = "0.1.0"

Then derive both Builder and ApplyTo on your struct:

use derive_builder::Builder;
use derive_builder_apply_to::ApplyTo;

#[derive(Builder, ApplyTo, Default, Debug, PartialEq)]
struct Person {
    name: String,
    age: u32,
    email: Option<String>,
}

fn main() {
    // Create an existing person
    let mut person = Person {
        name: "Alice".to_string(),
        age: 30,
        email: Some("alice@example.com".to_string()),
    };
    
    // Use builder to apply updates directly - no .build() needed!
    let changed = PersonBuilder::default()
        .age(31)
        .email(Some("alice.smith@example.com".to_string()))
        .apply_to(&mut person);
    
    assert!(changed);
    assert_eq!(person.name, "Alice"); // unchanged
    assert_eq!(person.age, 31);       // updated
    assert_eq!(person.email, Some("alice.smith@example.com".to_string())); // updated
    
    // Applying the same values again returns false
    let changed = PersonBuilder::default()
        .age(31)
        .apply_to(&mut person);
    assert!(!changed); // No change since age was already 31
}

How it works

The ApplyTo derive macro:

  1. Inspects your struct's fields
  2. Generates an apply_to method on the corresponding builder struct (e.g., PersonBuilder)
  3. The method iterates through each Option<T> field in the builder
  4. For each Some(value), it compares with the target struct's field
  5. Updates the target field only if the value is different
  6. Returns true if any field was changed, false otherwise

Requirements

  • Your struct must work with derive_builder (named fields only)
  • Field types must implement PartialEq for change detection
  • The builder struct must have Option<T> fields for optional updates

License

Licensed under the MIT License.