Macro project_uninit::project_uninit_mut[][src]

macro_rules! project_uninit_mut {
    ($expr:expr => {$( $($props:tt)=>+ ),* $(,)?}) => { ... };
    ($expr:expr => $($props:tt)=>+) => { ... };
}

Obtain &mut MaybeUninit<_> references to fields of a struct wrapped in MaybeUninit<_>.

This statically ensures that multiple references to the same value are not returned.

This must be used in an unsafe block or function when accessing fields of unions.

Syntax

// Access a single field:
let age: &mut MaybeUninit<u32> = project_uninit_mut!(bob => age);

// Access multiple fields:
let (age, id): (&mut MaybeUninit<_>, &mut MaybeUninit<_>) = project_uninit_mut!(
    bob => { age, id }
);

// Access fields of fields:
let first: &mut MaybeUninit<&str> = project_uninit_mut!(bob => name => first);

// Access fields of tuples (also works for tuple structs):
let id0: &mut MaybeUninit<usize> = project_uninit_mut!(bob => id => 0);

// Access multiple fields, including nested fields:
let (first, last, age, id0, id1) = project_uninit_mut!(bob => {
    name => first,
    name => last,
    age,
    id => 0,
    id => 1,
});

Example

use core::mem::MaybeUninit;
use project_uninit::project_uninit_mut;

#[derive(PartialEq, Eq, Debug)]
struct Person { name: Name, age: u32, id: (usize, usize) }
#[derive(PartialEq, Eq, Debug)]
struct Name { first: &'static str, last: &'static str }

let mut alice = MaybeUninit::<Person>::uninit();

let first = project_uninit_mut!(alice => name => first);
*first = MaybeUninit::new("Alice");

let (last, age, id0, id1) = project_uninit_mut!(alice => {
    name => last,
    age,
    id => 0,
    id => 1,
});

*last = MaybeUninit::new("Smith");
*age = MaybeUninit::new(22);
*id0 = MaybeUninit::new(123);
*id1 = MaybeUninit::new(456);

assert_eq!(unsafe { alice.assume_init() }, Person {
    name: Name { first: "Alice", last: "Smith" },
    age: 22,
    id: (123, 456),
});