macro_rules! project_uninit {
($expr:expr => {$( $($props:tt)=>+ ),* $(,)?}) => { ... };
($expr:expr => $($props:tt)=>+) => { ... };
}
Expand description
Obtain &MaybeUninit<_>
references to fields of a struct wrapped in MaybeUninit<_>
.
This must be used in an unsafe
block or function when accessing fields of unions.
§Syntax
// Access a single field:
let age: &MaybeUninit<u32> = project_uninit!(bob => age);
// Access multiple fields:
let (age, id): (&MaybeUninit<_>, &MaybeUninit<_>) = project_uninit!(
bob => { age, id }
);
// Access fields of fields:
let first: &MaybeUninit<&str> = project_uninit!(bob => name => first);
// Access fields of tuples (also works for tuple structs):
let id0: &MaybeUninit<usize> = project_uninit!(bob => id => 0);
// Access multiple fields, including nested fields:
let (first, last, age, id0, id1) = project_uninit!(bob => {
name => first,
name => last,
age,
id => 0,
id => 1,
});
§Example
use core::mem::MaybeUninit;
use project_uninit::project_uninit;
#[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 alice = MaybeUninit::new(Person {
name: Name { first: "Alice", last: "Smith" },
age: 22,
id: (123, 456),
});
let first = project_uninit!(alice => name => first);
assert_eq!(unsafe { first.assume_init() }, "Alice");
let (last, age, id1) = project_uninit!(alice => {
name => last,
age,
id => 1,
});
assert_eq!(unsafe { last.assume_init() }, "Smith");
assert_eq!(unsafe { age.assume_init() }, 22);
assert_eq!(unsafe { id1.assume_init() }, 456);