use super::errors::*;
use parking_lot::{MappedMutexGuard, MappedRwLockReadGuard, MappedRwLockWriteGuard};
use std::any::{Any, TypeId};
use std::ops::{Deref, DerefMut};
pub trait Unit<'a> {
type Borrowed: Deref<Target = dyn Any> + 'a;
type MutBorrowed: Deref<Target = dyn Any> + DerefMut + 'a;
fn insert_any(&self, new: Box<dyn Any>) -> Option<(Box<dyn Any>, ErrorDesc)>;
fn waiting_insert(&self, new: Box<dyn Any>) -> Option<(Box<dyn Any>, ErrorDesc)>
where
Self::Borrowed: Waitable,
Self::MutBorrowed: Waitable;
fn storage(&'a self) -> DynamicResult<Self::Borrowed>;
fn storage_mut(&'a self) -> DynamicResult<Self::MutBorrowed>;
fn waiting_storage(&'a self) -> Self::Borrowed
where
Self::Borrowed: Waitable;
fn waiting_storage_mut(&'a self) -> Self::MutBorrowed
where
Self::MutBorrowed: Waitable;
fn id(&self) -> TypeId;
}
pub trait Waitable {}
impl<'b, T: ?Sized> Waitable for MappedMutexGuard<'b, T> {}
impl<'b, T: ?Sized> Waitable for MappedRwLockReadGuard<'b, T> {}
impl<'b, T: ?Sized> Waitable for MappedRwLockWriteGuard<'b, T> {}
#[cfg(test)]
mod tests {
use super::Unit;
use crate::black_box::StorageUnit;
use crate::concurrent_black_box::RwLockUnit;
use std::any::TypeId;
#[test]
fn insert() {
let storage = RwLockUnit::new(StorageUnit::<usize>::new());
storage.insert_any(Box::new(0usize) as _);
storage.insert_any(Box::new(vec![1usize, 2, 3, 4]));
assert_eq!(
storage.inner().read().many().unwrap(),
&[0usize, 1, 2, 3, 4]
);
}
#[test]
fn waiting_insert() {
let storage = RwLockUnit::new(StorageUnit::<usize>::new());
storage.waiting_insert(Box::new(0usize) as _);
storage.waiting_insert(Box::new(vec![1usize, 2, 3, 4]));
assert_eq!(
storage.inner().read().many().unwrap(),
&[0usize, 1, 2, 3, 4]
);
}
#[test]
fn id() {
let storage = RwLockUnit::new(StorageUnit::<usize>::new());
assert_eq!(storage.id(), TypeId::of::<usize>());
}
#[test]
fn eq() {
let storage = RwLockUnit::new(StorageUnit::<usize>::new());
let storage_2 = RwLockUnit::new(StorageUnit::<usize>::new());
assert_eq!(storage.id(), storage_2.id());
}
}