macro_rules! project_uninit_mut {
($expr:expr => {$( $($props:tt)=>+ ),* $(,)?}) => { ... };
($expr:expr => $($props:tt)=>+) => { ... };
}Expand description
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),
});