matchmaker-partial 0.0.1

Support for partial updates and configuration in matchmaker
Documentation
# matchmaker-partial

Support for partial updates and configuration in matchmaker. This crate provides traits and logic for merging partial configuration structures, which is useful for overriding default settings with user-defined values.

## Features

- **Derive Macros**: Automatically generate partial versions of your structs where all fields are wrapped in `Option`.
- **Apply Updates**: Easily apply a partial struct to a full struct.
- **Dynamic Setting**: Update partial structs using string paths and values (ideal for CLI/environment overrides).
- **Nested Recursion**: Support for recursive partial updates in nested struct hierarchies.
- **Merging**: Merge multiple partial structs together.

## Example: Basic Usage

Using the `#[partial]` macro to generate a partial version of a struct and applying updates.

```rust
use matchmaker_partial::Apply;
use matchmaker_partial_macros::partial;

#[partial]
#[derive(Debug, PartialEq, Default)]
struct Config {
    pub name: String,
    pub threads: i32,
}

fn main() {
    let mut config = Config {
        name: "default".into(),
        threads: 4,
    };

    // The macro generates PartialConfig where all fields are Option
    let partial = PartialConfig {
        name: Some("custom".into()),
        threads: None, // This field won't be updated
    };

    // Apply the partial updates to the original struct
    config.apply(partial);

    assert_eq!(config.name, "custom");
    assert_eq!(config.threads, 4);
}
```

## Example: Dynamic Updates with `set`

The `set` method allows updating a partial struct using string paths and values. This requires the `#[partial(path)]` attribute.

```rust
use matchmaker_partial::{Set, Apply};
use matchmaker_partial_macros::partial;

#[partial(path)]
#[derive(Debug, Default)]
struct Config {
    pub name: String,
    pub threads: i32,
}

fn main() {
    let mut config = Config::default();
    let mut partial = PartialConfig::default();

    // Dynamically set values using string paths (e.g., from CLI flags)
    partial.set(&["name".to_string()], &["my-app".to_string()]).unwrap();
    partial.set(&["threads".to_string()], &["8".to_string()]).unwrap();

    config.apply(partial);

    assert_eq!(config.name, "my-app");
    assert_eq!(config.threads, 8);
}
```

## Example: Nested Structs with `recurse`

You can use `#[partial(recurse)]` to handle nested structures.

```rust
use matchmaker_partial::Apply;
use matchmaker_partial_macros::partial;

#[partial]
#[derive(Debug, Default, PartialEq, Clone)]
struct UIConfig {
    pub width: u32,
    pub height: u32,
}

#[partial]
#[derive(Debug, Default, PartialEq)]
struct AppConfig {
    pub name: String,
    #[partial(recurse)]
    pub ui: UIConfig,
}

fn main() {
    let mut config = AppConfig::default();
    
    let partial = PartialAppConfig {
        name: Some("Nested Example".into()),
        ui: PartialUIConfig {
            width: Some(1024),
            height: None,
        },
    };

    config.apply(partial);
    
    assert_eq!(config.ui.width, 1024);
    assert_eq!(config.ui.height, 0); // Original/Default value preserved
}
```