interior_mut/
lib.rs

1//! A crate for abstracting over interior mutable containers.
2
3#![cfg_attr(not(feature="std"), no_std)]
4
5mod lib {
6    #[cfg(feature="std")]
7    pub use std::*;
8    #[cfg(not(feature="std"))]
9    pub use core::*;
10}
11
12use lib::ops::DerefMut;
13use lib::cell::RefCell;
14
15/// A trait for obtaining a mutable reference on types that allow interior mutability.
16pub trait InteriorMut<'a, T> {
17
18    /// The reference type
19    type RefMut: DerefMut<Target=T> + 'a;
20
21    /// The error type
22    type Error;
23
24    /// Mutably borrows the internal value from an immutable reference.
25    fn borrow_int_mut(&'a self) -> Result<Self::RefMut, Self::Error>;
26}
27
28impl<'a, T: 'a> InteriorMut<'a, T> for RefCell<T> {
29    type RefMut = lib::cell::RefMut<'a, T>;
30    type Error = lib::cell::BorrowMutError;
31
32    fn borrow_int_mut(&'a self) -> Result<Self::RefMut, Self::Error> {
33        RefCell::try_borrow_mut(self)
34    }
35}
36
37#[cfg(feature="std")]
38impl<'a, T: 'a> InteriorMut<'a, T> for std::sync::Mutex<T> {
39    type RefMut = std::sync::MutexGuard<'a, T>;
40    type Error = std::sync::PoisonError<std::sync::MutexGuard<'a, T>>;
41
42    fn borrow_int_mut(&'a self) -> std::sync::LockResult<std::sync::MutexGuard<'a, T>> {
43        self.lock()
44    }
45}
46
47#[cfg(feature="std")]
48impl<'a, T: 'a> InteriorMut<'a, T> for std::sync::RwLock<T> {
49    type RefMut = std::sync::RwLockWriteGuard<'a, T>;
50    type Error = std::sync::PoisonError<std::sync::RwLockWriteGuard<'a, T>>;
51
52    fn borrow_int_mut(&'a self) -> std::sync::LockResult<std::sync::RwLockWriteGuard<'a, T>> {
53        self.write()
54    }
55}