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.

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.

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.

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
}