Skip to content

maxstate/munge

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

munge

munge makes it easy and safe to destructure raw pointers, MaybeUninits, Cells, and Pins.

Just use the munge! macro to destructure opaque types the same way you'd destructure a value.

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

Examples

munge makes it easy to initialize MaybeUninits:

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

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

let mut mu = MaybeUninit::<Example>::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);

It can also be used to destructure Cells:

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

And Pins as long as all fields are structurally pinned:

use {
    ::core::{marker::PhantomPinned, pin::Pin},
    ::munge::{munge, StructuralPinning},
};

struct Example {
    pub a: u32,
    pub b: char,
    pub _phantom: PhantomPinned,
}

// SAFETY: `Example` obeys structural pinning.
unsafe impl StructuralPinning for Example {}

let mut value = Example {
    a: 0,
    b: ' ',
    _phantom: PhantomPinned,
};
// SAFETY: `value` will not be moved before being dropped.
let mut pin = unsafe { Pin::new_unchecked(&mut value) };

munge!(let Example { a, b, .. } = pin.as_mut());
*a.get_mut() = 1;
*b.get_mut() = 'a';

assert_eq!(pin.as_mut().into_ref().a, 1);
assert_eq!(pin.as_mut().into_ref().b, 'a');
assert_eq!(value.a, 1);
assert_eq!(value.b, 'a');

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

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Rust 100.0%