Macro assign::assign

source ·
macro_rules! assign {
    ($initial_value:expr, {
        $( $field:ident $( : $value:expr )? ),+ $(,)?
    }) => { ... };
    (@assign $item:ident $field:ident : $value:expr) => { ... };
    (@assign $item:ident $field:ident) => { ... };
}
Expand description

Mutate a struct value in a declarative style.

§Basic usage

#[non_exhaustive]
#[derive(Debug, PartialEq)]
struct SomeStruct {
    a: u32,
    b: Option<f32>,
    c: String,
}

impl SomeStruct {
    fn new() -> Self {
        // ...
    }
}

let instance1 = assign!(SomeStruct::new(), {
    a: 2,
    c: "new".into(),
});

// The same thing using mutation explicitly.
// This is what the above expands to.
let instance2 = {
    let mut item = SomeStruct::new();
    item.a = 2;
    item.c = "new".into();
    item
};

// The same thing using struct update syntax (does not work for
// non-exhaustive structs defined in external crates).
let instance3 = SomeStruct {
    a: 2,
    c: "new".into(),
    ..SomeStruct::new()
};

assert_eq!(instance1, instance2);
assert_eq!(instance1, instance3);

§Slightly more realistic example

// in awesome_cli_lib
#[non_exhaustive]
struct ArgOptions {
    pub name: String,
    pub short: Option<String>,
    pub long: Option<String>,
    pub help: Option<String>,
    pub required: bool,
    pub takes_value: bool,
    pub multiple: bool,
    pub default_value: Option<String>,
}

impl ArgOptions {
    pub fn new(name: String) -> Self {
        // ...
    }
}

// your crate
use assign::assign;

let arg = Arg::new(assign!(ArgOptions::new("version".into()), {
    short: Some("V".into()),
    long: Some("version".into()),
    help: Some("prints the version and quits.".into()),
}));