alopt 1.0.0

a Rust crate providing efficient synchronization primitives that integrate Option into their design.
Documentation
use super::{Wom, Worl};

pub struct WorlGuardRead<'a, T: 'a> {
    worl: &'a Worl<T>,
}

pub struct WorlGuardWrite<'a, T: 'a> {
    worl: &'a Worl<T>,
}

pub struct WomGuard<'a, T: 'a> {
    wom: &'a Wom<T>,
}

impl<'a, T: 'a> WorlGuardRead<'a, T> {
    pub(super) fn new(worl: &'a Worl<T>) -> Self {
        Self { worl }
    }
}

impl<'a, T: 'a> WorlGuardWrite<'a, T> {
    pub(super) fn new(worl: &'a Worl<T>) -> Self {
        Self { worl }
    }

    pub fn clear(self) {
        unsafe {
            *self.worl.data.get() = None;
        }
    }

    pub fn set(&self, data: T) {
        unsafe {
            *self.worl.data.get() = Some(data);
        }
    }

    pub fn swap(&self, data: &mut T) -> bool {
        let current = unsafe { &mut *self.worl.data.get() }.as_mut();
        if let Some(cur) = current {
            std::mem::swap(data, cur);
            true
        } else {
            false
        }
    }
}

impl<'a, T: 'a> WomGuard<'a, T> {
    pub(super) fn new(wom: &'a Wom<T>) -> Self {
        Self { wom }
    }

    pub fn clear(self) {
        unsafe {
            *self.wom.data.get() = None;
        }
    }

    pub fn set(&self, data: T) {
        unsafe {
            *self.wom.data.get() = Some(data);
        }
    }

    pub fn swap(&self, data: &mut T) {
        std::mem::swap(data, self.wom.data_as_mut().unwrap());
    }
}

impl<'a, T: 'a> std::ops::Deref for WorlGuardRead<'a, T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        let data_outer = unsafe { &*self.worl.data.get() };
        data_outer.as_ref().unwrap()
    }
}

impl<'a, T: 'a> std::ops::Deref for WorlGuardWrite<'a, T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        let data_outer = unsafe { &*self.worl.data.get() };
        data_outer.as_ref().unwrap()
    }
}

impl<'a, T: 'a> std::ops::DerefMut for WorlGuardWrite<'a, T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        let data_outer = unsafe { &mut *self.worl.data.get() };
        data_outer.as_mut().unwrap()
    }
}

impl<'a, T: 'a> Drop for WorlGuardRead<'a, T> {
    fn drop(&mut self) {
        self.worl.sem.release_read();
    }
}

impl<'a, T: 'a> Drop for WorlGuardWrite<'a, T> {
    fn drop(&mut self) {
        self.worl.sem.release_write();
    }
}

impl<'a, T: 'a> std::ops::Deref for WomGuard<'a, T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        self.wom.data_as_mut().unwrap()
    }
}

impl<'a, T: 'a> std::ops::DerefMut for WomGuard<'a, T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.wom.data_as_mut().unwrap()
    }
}

impl<'a, T: 'a> Drop for WomGuard<'a, T> {
    fn drop(&mut self) {
        self.wom.release();
    }
}