use std::error::Error;
use std::fmt::{self, Debug, Display};
use std::sync::{Mutex as StdMutex, MutexGuard, TryLockError};
#[derive(Default)]
pub struct Mutex<T: ?Sized> {
std: StdMutex<T>,
}
impl<T> Mutex<T> {
pub fn new(value: T) -> Mutex<T> {
Mutex {
std: StdMutex::new(value),
}
}
pub fn into_inner(self) -> T {
match self.std.into_inner() {
Ok(value) => value,
Err(_) => panic!("mutex is poisoned"),
}
}
}
impl<T: ?Sized> Mutex<T> {
pub fn lock(&self) -> MutexGuard<T> {
match self.std.lock() {
Ok(guard) => guard,
Err(_) => panic!("mutex is poisoned"),
}
}
pub fn try_lock(&self) -> Result<MutexGuard<T>, WouldBlock> {
match self.std.try_lock() {
Ok(guard) => Ok(guard),
Err(TryLockError::Poisoned(_)) => panic!("mutex is poisoned"),
Err(TryLockError::WouldBlock) => Err(WouldBlock),
}
}
pub fn get_mut(&mut self) -> &mut T {
match self.std.get_mut() {
Ok(value) => value,
Err(_) => panic!("mutex is poisoned"),
}
}
}
impl<T> From<T> for Mutex<T> {
fn from(value: T) -> Self {
Mutex {
std: StdMutex::from(value),
}
}
}
impl<T: ?Sized + Debug> Debug for Mutex<T> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.std, formatter)
}
}
#[derive(Debug)]
pub struct WouldBlock;
impl Display for WouldBlock {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&TryLockError::WouldBlock::<()>, formatter)
}
}
impl Error for WouldBlock {}