derive_builder_apply_to 0.1.0

A procedural macro for generating apply_to methods for builder patterns
Documentation
# derive-builder-apply-to

A procedural macro for generating `apply_to` methods for builder patterns, designed to work seamlessly with the [`derive_builder`](https://crates.io/crates/derive_builder) crate.

## Overview

The [`derive_builder`](https://crates.io/crates/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`:

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

Then derive both `Builder` and `ApplyTo` on your struct:

```rust
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.