project-uninit

Rust macros for safe (and unsafe) access to and initialization of fields of structs wrapped in MaybeUninit<_>

This crate uses the ptr::addr_of! and ptr::addr_of_mut! macros introduced in Rust 1.51 to avoid undefined behavior.

See the docs for more information and examples.

Examples

Initialize a struct one field at a time

```rust use core::mem::MaybeUninit; use projectuninit::partialinit;

[derive(PartialEq, Eq, Debug)]

struct Inner { value1: u8, value2: (i32, bool) }

[derive(PartialEq, Eq, Debug)]

struct MyStruct { name: &'static str, inner: Inner }

let mut target = MaybeUninit::::uninit();

let name: &mut &str = partialinit!(target => name = "Foo"); asserteq!(*name, "Foo"); *name = "Bar";

let (value1, value20): (&mut u8, &mut i32) = partialinit!(target => { inner => value1: 0xff, inner => value2 => 0: 1000, }); asserteq!(*value1, 0xff); asserteq!(*value20, 1000); *value20 *= 2;

let value21: &mut bool = partialinit!(target => inner => value2 => 1 = true); asserteq!(*value21, true);

asserteq!(unsafe { target.assumeinit() }, MyStruct { name: "Bar", inner: Inner { value1: 0xff, value2: (2000, true) }, }); ```

Obtain references to fields of a MaybeUninit<_> struct

```rust

use core::mem::MaybeUninit;

use projectuninit::projectuninit;

[derive(PartialEq, Eq, Debug)]

struct Person { name: &'static str, age: u32 } let person = MaybeUninit::new(Person { name: "Alice", age: 22, }); let (name, age): (&MaybeUninit<&str>, &MaybeUninit) = project_uninit!( person => { name, age } );

asserteq!(unsafe { name.assumeinit() }, "Alice"); asserteq!(unsafe { age.assumeinit() }, 22);

```

Obtain mutable references to fields of a MaybeUninit<_> struct

```rust

use core::mem::MaybeUninit;

#[derive(PartialEq, Eq, Debug)]

struct Person { name: &'static str, age: u32 }

use projectuninit::projectuninit_mut;

let mut person = MaybeUninit::new(Person { name: "Alice", age: 22, });

let (name, age): (&mut MaybeUninit<&str>, &mut MaybeUninit) = projectuninitmut!( person => { name, age } );

*name = MaybeUninit::new("Alicia"); *age = MaybeUninit::new(24);

asserteq!(unsafe { person.assumeinit() }, Person { name: "Alicia", age: 24, }); ```