munge makes it easy and safe to destructure MaybeUninits, Cells, UnsafeCells, ManuallyDrops, and more.

Just use the munge! macro to destructure opaque types the same way you'd destructure a value. The munge! macro may be used to perform either borrow destructuring (e.g. let (a, b) = c where c is a reference) or move destructuring (e.g. let (a, b) = c where c is a value) depending on the type.

munge has no features and is always #![no_std].

Examples

munge makes it easy to initialize MaybeUninits:

```rust use { ::core::mem::MaybeUninit, ::munge::munge, };

pub struct Example { a: u32, b: (char, f32), }

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

munge!(let Example { a, b: (c, mut f) } = &mut mu); asserteq!(a.write(10), &10); asserteq!(c.write('x'), &'x'); assert_eq!(f.write(3.14), &3.14); // Note that mut bindings can be reassigned like you'd expect: f = &mut MaybeUninit::uninit();

// SAFETY: mu is completely initialized. let init = unsafe { mu.assumeinit() }; asserteq!(init.a, 10); asserteq!(init.b.0, 'x'); asserteq!(init.b.1, 3.14); ```

It can also be used to destructure Cells:

```rust use { ::core::cell::Cell, ::munge::munge, };

pub struct Example { a: u32, b: (char, f32), }

let value = Example { a: 10, b: ('x', 3.14), }; let cell = Cell::::new(value);

munge!(let Example { a, b: (c, f) } = &cell); asserteq!(a.get(), 10); a.set(42); asserteq!(c.get(), 'x'); c.set('!'); assert_eq!(f.get(), 3.14); f.set(1.41);

let value = cell.intoinner(); asserteq!(value.a, 42); asserteq!(value.b.0, '!'); asserteq!(value.b.1, 1.41); ```

You can even extend munge to work with your own types by implementing its Destructure and Restructure traits:

```rust use munge::{Destructure, Restructure, Move, munge};

pub struct Invariant(T);

impl Invariant { /// # Safety /// /// value must uphold my custom invariant. pub unsafe fn new_unchecked(value: T) -> Self { Self(value) }

pub fn unwrap(self) -> T {
    self.0
}

}

// SAFETY: // - Invariant<T> is destructured by move, so its Destructuring type is // Move. // - underlying returns a pointer to its inner type, so it is guaranteed // to be non-null, properly aligned, and valid for reads. unsafe impl Destructure for Invariant { type Underlying = T; type Destructuring = Move;

fn underlying(&mut self) -> *mut Self::Underlying {
    &mut self.0 as *mut Self::Underlying
}

}

// SAFETY: restructure returns an Invariant<U> that takes ownership of // the restructured field because Invariant<T> is destructured by move. unsafe impl Restructure for Invariant { type Restructured = Invariant;

unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
    // SAFETY: The caller has guaranteed that `ptr` is a pointer to a
    // subfield of some `T`, so it must be properly aligned, valid for
    // reads, and initialized. We may move the fields because the
    // destructuring type for `Invariant<T>` is `Move`.
    let value = unsafe { ptr.read() };
    Invariant(value)
}

}

// SAFETY: (1, 2, 3) upholds my custom invariant. let value = unsafe { Invariant::newunchecked((1, 2, 3)) }; munge!(let (one, two, three) = value); asserteq!(one.unwrap(), 1); asserteq!(two.unwrap(), 2); asserteq!(three.unwrap(), 3); ```