use std::ops::{Deref, DerefMut};
pub use self::cell::*;
pub use self::rc::*;
pub use self::sync::*;
pub struct Nested<T, Inner: Deref<Target = T>, Outer> {
inner: Inner,
#[allow(dead_code)]
outer: Outer,
}
impl<T, Inner: Deref<Target = T>, Outer> Deref for Nested<T, Inner, Outer> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.inner.deref()
}
}
impl<T, Inner: DerefMut<Target = T>, Outer> DerefMut for Nested<T, Inner, Outer> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.inner.deref_mut()
}
}
unsafe fn remove_lifetime<'b, T>(x: &T) -> &'b T {
unsafe { &*(x as *const T) }
}
mod cell {
use std::cell::*;
use super::*;
pub trait NestedRefCell<'a, T>: Deref<Target = RefCell<T>> + Sized + 'a {
fn nest_borrow(self) -> Nested<T, Ref<'a, T>, Self> {
let me = unsafe { remove_lifetime(&self) };
let inner = RefCell::borrow(me);
Nested { inner, outer: self }
}
fn nest_try_borrow(self) -> Result<Nested<T, Ref<'a, T>, Self>, BorrowError> {
let me = unsafe { remove_lifetime(&self) };
let inner = RefCell::try_borrow(me)?;
Ok(Nested { inner, outer: self })
}
fn nest_borrow_mut(self) -> Nested<T, RefMut<'a, T>, Self> {
let me = unsafe { remove_lifetime(&self) };
let inner = RefCell::borrow_mut(me);
Nested { inner, outer: self }
}
fn nest_try_borrow_mut(self) -> Result<Nested<T, RefMut<'a, T>, Self>, BorrowMutError> {
let me = unsafe { remove_lifetime(&self) };
let inner = RefCell::try_borrow_mut(me)?;
Ok(Nested { inner, outer: self })
}
}
impl<'a, T, Outer: Deref<Target = RefCell<T>> + Sized + 'a> NestedRefCell<'a, T> for Outer {}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_many_refcell() {
let x = RefCell::new(RefCell::new(RefCell::new(0)));
{
let z = x.borrow().nest_borrow().nest_borrow();
assert_eq!(0, *z);
}
{
let z = x
.try_borrow()
.unwrap()
.nest_try_borrow()
.unwrap()
.nest_try_borrow()
.unwrap();
assert_eq!(0, *z);
}
{
let mut z = x.borrow().nest_borrow().nest_borrow_mut();
*z = 1;
assert_eq!(1, *z);
}
{
{
let mut y = x.borrow().nest_borrow_mut();
*y = RefCell::new(2);
}
let z = x.borrow().nest_borrow().nest_borrow();
assert_eq!(2, *z);
}
}
}
}
mod rc {
use std::rc::*;
use super::*;
pub trait NestedRcWeak<'a, T>: Deref<Target = Weak<T>> + Sized + 'a {
fn nest_upgrade(self) -> Option<Nested<T, Rc<T>, Self>> {
let inner = Weak::upgrade(&self)?;
Some(Nested { inner, outer: self })
}
}
impl<'a, T, Outer: Deref<Target = Weak<T>> + Sized + 'a> NestedRcWeak<'a, T> for Outer {}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_many_rc() {
let x1: Rc<i32> = Rc::new(0);
let y1: Weak<i32> = Rc::downgrade(&x1);
let x2: Rc<Weak<i32>> = Rc::new(y1);
let y2: Weak<Weak<i32>> = Rc::downgrade(&x2);
let x3: Rc<Weak<Weak<i32>>> = Rc::new(y2);
let y3: Weak<Weak<Weak<i32>>> = Rc::downgrade(&x3);
let z = y3
.upgrade()
.unwrap()
.nest_upgrade()
.unwrap()
.nest_upgrade()
.unwrap();
assert_eq!(0, *z);
}
}
}
mod sync {
use std::sync::*;
use super::*;
pub trait NestedArcWeak<'a, T>: Deref<Target = Weak<T>> + Sized + 'a {
fn nest_upgrade(self) -> Option<Nested<T, Arc<T>, Self>> {
let inner = Weak::upgrade(&self)?;
Some(Nested { inner, outer: self })
}
}
impl<'a, T, Outer: Deref<Target = Weak<T>> + Sized + 'a> NestedArcWeak<'a, T> for Outer {}
pub trait NestedMutex<'a, T>: Deref<Target = Mutex<T>> + Sized + 'a {
fn nest_lock(self) -> LockResult<Nested<T, MutexGuard<'a, T>, Self>> {
let me = unsafe { remove_lifetime(&self) };
match me.lock() {
Ok(inner) => Ok(Nested { inner, outer: self }),
Err(err) => {
let inner = err.into_inner();
Err(PoisonError::new(Nested { inner, outer: self }))
}
}
}
fn nest_try_lock(self) -> TryLockResult<Nested<T, MutexGuard<'a, T>, Self>> {
let me = unsafe { remove_lifetime(&self) };
match me.try_lock() {
Ok(inner) => Ok(Nested { inner, outer: self }),
Err(err) => match err {
TryLockError::Poisoned(err) => {
let inner = err.into_inner();
Err(TryLockError::Poisoned(PoisonError::new(Nested {
inner,
outer: self,
})))
}
TryLockError::WouldBlock => Err(TryLockError::WouldBlock),
},
}
}
}
impl<'a, T, Outer: Deref<Target = Mutex<T>> + Sized + 'a> NestedMutex<'a, T> for Outer {}
pub trait NestedRwLock<'a, T>: Deref<Target = RwLock<T>> + Sized + 'a {
fn nest_try_read(self) -> TryLockResult<Nested<T, RwLockReadGuard<'a, T>, Self>> {
let me = unsafe { remove_lifetime(&self) };
match me.try_read() {
Ok(inner) => Ok(Nested { inner, outer: self }),
Err(err) => match err {
TryLockError::Poisoned(err) => {
let inner = err.into_inner();
Err(TryLockError::Poisoned(PoisonError::new(Nested {
inner,
outer: self,
})))
}
TryLockError::WouldBlock => Err(TryLockError::WouldBlock),
},
}
}
fn nest_try_write(self) -> TryLockResult<Nested<T, RwLockWriteGuard<'a, T>, Self>> {
let me = unsafe { remove_lifetime(&self) };
match me.try_write() {
Ok(inner) => Ok(Nested { inner, outer: self }),
Err(err) => match err {
TryLockError::Poisoned(err) => {
let inner = err.into_inner();
Err(TryLockError::Poisoned(PoisonError::new(Nested {
inner,
outer: self,
})))
}
TryLockError::WouldBlock => Err(TryLockError::WouldBlock),
},
}
}
}
impl<'a, T, Outer: Deref<Target = RwLock<T>> + Sized + 'a> NestedRwLock<'a, T> for Outer {}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_many_arc() {
let x1: Arc<i32> = Arc::new(0);
let y1: Weak<i32> = Arc::downgrade(&x1);
let x2: Arc<Weak<i32>> = Arc::new(y1);
let y2: Weak<Weak<i32>> = Arc::downgrade(&x2);
let x3: Arc<Weak<Weak<i32>>> = Arc::new(y2);
let y3: Weak<Weak<Weak<i32>>> = Arc::downgrade(&x3);
let z = y3
.upgrade()
.unwrap()
.nest_upgrade()
.unwrap()
.nest_upgrade()
.unwrap();
assert_eq!(0, *z);
}
#[test]
fn test_many_rwlock() {
let x = RwLock::new(RwLock::new(RwLock::new(0)));
{
let z = x
.try_read()
.unwrap()
.nest_try_read()
.unwrap()
.nest_try_read()
.unwrap();
assert_eq!(0, *z);
}
{
let z = x
.try_read()
.unwrap()
.nest_try_read()
.unwrap()
.nest_try_read()
.unwrap();
assert_eq!(0, *z);
}
{
let mut z = x
.try_read()
.unwrap()
.nest_try_read()
.unwrap()
.nest_try_write()
.unwrap();
*z = 1;
assert_eq!(1, *z);
}
{
{
let mut y = x.try_read().unwrap().nest_try_write().unwrap();
*y = RwLock::new(2);
}
let z = x
.try_read()
.unwrap()
.nest_try_read()
.unwrap()
.nest_try_read()
.unwrap();
assert_eq!(2, *z);
}
}
#[test]
fn test_many_mutex() {
let x = RwLock::new(RwLock::new(RwLock::new(0)));
{
let z = x
.try_read()
.unwrap()
.nest_try_read()
.unwrap()
.nest_try_read()
.unwrap();
assert_eq!(0, *z);
}
{
let z = x
.try_read()
.unwrap()
.nest_try_read()
.unwrap()
.nest_try_read()
.unwrap();
assert_eq!(0, *z);
}
{
let mut z = x
.try_read()
.unwrap()
.nest_try_read()
.unwrap()
.nest_try_write()
.unwrap();
*z = 1;
assert_eq!(1, *z);
}
{
{
let mut y = x.try_read().unwrap().nest_try_write().unwrap();
*y = RwLock::new(2);
}
let z = x
.try_read()
.unwrap()
.nest_try_read()
.unwrap()
.nest_try_read()
.unwrap();
assert_eq!(2, *z);
}
}
}
}
#[cfg(test)]
mod test {
use std::cell::*;
use std::mem;
use std::rc::*;
use super::*;
#[test]
fn test_rc_refcell() {
let x = Rc::new(RefCell::new(0));
let x = Rc::downgrade(&x);
assert_eq!(0, *x.upgrade().unwrap().borrow());
{
let z = x.upgrade().unwrap().nest_borrow();
assert_eq!(0, *z);
}
}
#[test]
fn test_reassign_refcell_stack() {
let x = RefCell::new(RefCell::new(0));
let ys: Vec<_> = (1..10).map(|i| RefCell::new(RefCell::new(i))).collect();
let mut ref1 = x.borrow().nest_borrow_mut();
for y in ys.iter() {
let mut yref = y.borrow().nest_borrow_mut();
mem::swap(ref1.deref_mut(), yref.deref_mut());
ref1 = yref;
}
}
}