restor 2.0.2

A dynamic resource storage system in rust.
Documentation
use std::any::{Any, TypeId};

use super::black_box::{
    DynamicResult,
    ErrorDesc::{self, *},
    StorageUnit, Unit,
};
mod newtype;
pub use newtype::{MutexStorage, RwLockStorage};
use parking_lot::{
    MappedMutexGuard, MappedRwLockReadGuard, MappedRwLockWriteGuard, Mutex, MutexGuard, RwLock,
    RwLockReadGuard, RwLockWriteGuard,
};

#[repr(transparent)]
pub struct MutexUnit<T> {
    inner: Mutex<T>,
}

impl<T> MutexUnit<T> {
    pub fn new(data: T) -> Self {
        Self {
            inner: Mutex::new(data),
        }
    }
}

impl<'a, T: 'static + Send> Unit<'a> for MutexUnit<StorageUnit<T>> {
    type Borrowed = MappedMutexGuard<'a, dyn Any>;
    type MutBorrowed = MappedMutexGuard<'a, dyn Any>;
    fn insert_any(&self, new: Box<dyn Any>) -> Option<(Box<dyn Any>, ErrorDesc)> {
        let newtype = new.type_id();
        if let Some(mut x) = self.inner.try_lock() {
            if new.is::<T>() {
                x.insert(*new.downcast::<T>().unwrap_or_else(|_| {
                    panic!(
                        "Tried to insert an object with type {:?} into a storage of type {:?}",
                        newtype,
                        TypeId::of::<T>()
                    )
                }));
                None
            } else if new.is::<Vec<T>>() {
                x.insert_many(*new.downcast::<Vec<T>>().unwrap());
                None
            } else {
                Some((new, ErrorDesc::NoMatchingType))
            }
        } else {
            Some((new, ErrorDesc::BorrowedIncompatibly))
        }
    }
    fn waiting_insert(&self, new: Box<dyn Any>) -> Option<(Box<dyn Any>, ErrorDesc)> {
        let newtype = new.type_id();
        if new.is::<T>() || new.is::<Vec<T>>() {
            let mut x = self.inner.lock();
            if new.is::<T>() {
                x.insert(*new.downcast::<T>().unwrap_or_else(|_| {
                    panic!(
                        "Tried to insert an object with type {:?} into a storage of type {:?}",
                        newtype,
                        TypeId::of::<T>()
                    )
                }));
                None
            } else {
                x.insert_many(*new.downcast::<Vec<T>>().unwrap());
                None
            }
        } else {
            Some((new, ErrorDesc::NoMatchingType))
        }
    }
    fn storage(&'a self) -> DynamicResult<MappedMutexGuard<'a, dyn Any>> {
        self.inner
            .try_lock()
            .map(|x| MutexGuard::map::<dyn Any, _>(x, |z| &mut *z))
            .ok_or(BorrowedIncompatibly)
    }
    fn storage_mut(&'a self) -> DynamicResult<MappedMutexGuard<'a, dyn Any>> {
        self.storage()
    }

    fn waiting_storage(&'a self) -> MappedMutexGuard<'a, dyn Any> {
        MutexGuard::map::<dyn Any, _>(self.inner.lock(), |z| &mut *z)
    }
    fn waiting_storage_mut(&'a self) -> MappedMutexGuard<'a, dyn Any> {
        self.waiting_storage()
    }

    fn id(&self) -> TypeId {
        TypeId::of::<T>()
    }
}

#[repr(transparent)]
pub struct RwLockUnit<T> {
    inner: RwLock<T>,
}

impl<T> RwLockUnit<T> {
    pub fn new(data: T) -> Self {
        Self {
            inner: RwLock::new(data),
        }
    }
    #[cfg(test)]
    pub fn inner(&self) -> &RwLock<T> {
        &self.inner
    }
}

impl<'a, T: 'static + Send> Unit<'a> for RwLockUnit<StorageUnit<T>> {
    type Borrowed = MappedRwLockReadGuard<'a, dyn Any>;
    type MutBorrowed = MappedRwLockWriteGuard<'a, dyn Any>;

    fn insert_any(&self, new: Box<dyn Any>) -> Option<(Box<dyn Any>, ErrorDesc)> {
        let newtype = new.type_id();
        if let Some(mut x) = self.inner.try_write() {
            if new.is::<T>() {
                x.insert(*new.downcast::<T>().unwrap_or_else(|_| {
                    panic!(
                        "Tried to insert an object with type {:?} into a storage of type {:?}",
                        newtype,
                        TypeId::of::<T>()
                    )
                }));
                None
            } else if new.is::<Vec<T>>() {
                x.insert_many(*new.downcast::<Vec<T>>().unwrap());
                None
            } else {
                Some((new, ErrorDesc::NoMatchingType))
            }
        } else {
            Some((new, ErrorDesc::BorrowedIncompatibly))
        }
    }

    fn waiting_insert(&self, new: Box<dyn Any>) -> Option<(Box<dyn Any>, ErrorDesc)> {
        let newtype = new.type_id();
        if new.is::<T>() || new.is::<Vec<T>>() {
            let mut x = self.inner.write();
            if new.is::<T>() {
                x.insert(*new.downcast::<T>().unwrap_or_else(|_| {
                    panic!(
                        "Tried to insert an object with type {:?} into a storage of type {:?}",
                        newtype,
                        TypeId::of::<T>()
                    )
                }));
                None
            } else {
                x.insert_many(*new.downcast::<Vec<T>>().unwrap());
                None
            }
        } else {
            Some((new, ErrorDesc::NoMatchingType))
        }
    }

    fn storage(&'a self) -> DynamicResult<MappedRwLockReadGuard<'a, dyn Any>> {
        self.inner
            .try_read()
            .map(|x| RwLockReadGuard::map::<dyn Any, _>(x, |z| &*z))
            .ok_or(BorrowedIncompatibly)
    }
    fn storage_mut(&'a self) -> DynamicResult<MappedRwLockWriteGuard<'a, dyn Any>> {
        self.inner
            .try_write()
            .map(|x| RwLockWriteGuard::map::<dyn Any, _>(x, |z| &mut *z))
            .ok_or(BorrowedIncompatibly)
    }

    fn waiting_storage(&'a self) -> MappedRwLockReadGuard<'a, dyn Any> {
        RwLockReadGuard::map::<dyn Any, _>(self.inner.read(), |z| &*z)
    }
    fn waiting_storage_mut(&'a self) -> MappedRwLockWriteGuard<'a, dyn Any> {
        RwLockWriteGuard::map::<dyn Any, _>(self.inner.write(), |z| &mut *z)
    }

    fn id(&self) -> TypeId {
        TypeId::of::<T>()
    }
}