Macro project_uninit::project_uninit[][src]

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

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);