notifies 0.1.0

various efficient async notifies
Documentation
//! # Volunary mutex
//!
//! Simple mutex which can be acquired only in non-waiting manner.

use std::{
    cell::UnsafeCell,
    ops::{Deref, DerefMut},
    sync::atomic::{
        AtomicBool,
        Ordering::{Acquire, Relaxed, Release},
    },
};

pub struct VolMutex<T> {
    mutex: RawVolMutex,
    data: UnsafeCell<T>,
}

unsafe impl<T: Send> Send for VolMutex<T> {}
unsafe impl<T: Send> Sync for VolMutex<T> {}

impl<T> VolMutex<T> {
    pub const fn new(data: T) -> Self {
        Self {
            mutex: RawVolMutex::new(),
            data: UnsafeCell::new(data),
        }
    }

    pub fn try_lock(&self) -> Option<VolGuard<'_, T>> {
        self.mutex.try_lock().map(|guard| VolGuard {
            _guard: guard,
            data: &self.data,
        })
    }
}

pub struct VolGuard<'a, T> {
    _guard: RawVolGuard<'a>,
    data: &'a UnsafeCell<T>,
}

impl<T> DerefMut for VolGuard<'_, T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { &mut *self.data.get() }
    }
}

impl<T> Deref for VolGuard<'_, T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        unsafe { &*self.data.get() }
    }
}

#[derive(Debug, Default)]
pub struct RawVolMutex {
    flag: AtomicBool,
}

impl RawVolMutex {
    pub const fn new() -> Self {
        Self {
            flag: AtomicBool::new(false),
        }
    }

    pub fn try_lock(&self) -> Option<RawVolGuard<'_>> {
        self.flag
            .compare_exchange(false, true, Acquire, Relaxed)
            .is_ok()
            .then_some(RawVolGuard(&self.flag))
    }
}

pub struct RawVolGuard<'a>(&'a AtomicBool);

impl Drop for RawVolGuard<'_> {
    fn drop(&mut self) {
        self.0.store(false, Release);
    }
}