refutil 0.1.1

Various utilities for reference, lifetime and memory management
Documentation
//! Various utils for reference, lifetime and memory management.
#![no_std]

#[cfg(feature = "std")]
extern crate std;

pub mod revref;
pub mod dropref;

pub use revref::{RevMut, RevertCheck};
pub use dropref::DropMut;

/// Replaces object behind a mutable reference with another one. This is a more
/// generic version of [`std::mem::replace`].
pub fn replace<T, U>(data: &mut T, update: impl FnOnce(T) -> (T, U)) -> U {
    let data = &raw mut *data;
    // SAFETY: `data` was created from a reference so it is valid in all means.
    // Also we do `read` then `write` on the same location, so no double free.
    unsafe {
        let (new, side) = update(data.read());
        data.write(new);
        side
    }
}

/// Replaces object behind a mutable reference with another one. This is a more
/// generic version of [`std::mem::replace`].
pub async fn replace_async<T, U>(data: &mut T, update: impl AsyncFnOnce(T) -> (T, U)) -> U {
    let data = &raw mut *data;
    // SAFETY: `data` was created from a reference so it is valid in all means.
    // Also we do `read` then `write` on the same location, so no double free.
    unsafe {
        let (new, side) = update(data.read()).await;
        data.write(new);
        side
    }
}