# `munge` [![crates.io badge]][crates.io] [![docs badge]][docs] [![license badge]][license] [crates.io badge]: https://img.shields.io/crates/v/munge.svg [crates.io]: https://crates.io/crates/munge [docs badge]: https://img.shields.io/docsrs/munge [docs]: https://docs.rs/munge [license badge]: https://img.shields.io/badge/license-MIT-blue.svg [license]: https://github.com/rkyv/munge/blob/master/LICENSE Munge makes it easy and safe to destructure `MaybeUninit`s, `Cell`s, `UnsafeCell`s, `ManuallyDrop`s, and more. ## Documentation - [munge](https://docs.rs/munge), the core library - [munge_macro](https://docs.rs/munge_macro), the proc macro at the core of munge. ## Examples Initialize `MaybeUninit`s: ```rust use core::mem::MaybeUninit; use 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); assert_eq!(a.write(10), &10); assert_eq!(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.assume_init() }; assert_eq!(init.a, 10); assert_eq!(init.b.0, 'x'); assert_eq!(init.b.1, 3.14); ``` Destructure `Cell`s: ```rust use core::cell::Cell; use 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); assert_eq!(a.get(), 10); a.set(42); assert_eq!(c.get(), 'x'); c.set('!'); assert_eq!(f.get(), 3.14); f.set(1.41); let value = cell.into_inner(); assert_eq!(value.a, 42); assert_eq!(value.b.0, '!'); assert_eq!(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` 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` that takes ownership of // the restructured field because `Invariant` 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` is `Move`. let value = unsafe { ptr.read() }; Invariant(value) } } // SAFETY: `(1, 2, 3)` upholds my custom invariant. let value = unsafe { Invariant::new_unchecked((1, 2, 3)) }; munge!(let (one, two, three) = value); assert_eq!(one.unwrap(), 1); assert_eq!(two.unwrap(), 2); assert_eq!(three.unwrap(), 3); ```