use core::{fmt::{Debug, Display}, ops::{Deref, DerefMut}};
use spin::RwLock as SpinRwLock;
use crate::sync::{PoisonError, TryLockError};
#[derive(Debug, Default)]
pub struct RwLock<T: ?Sized> {
lock: SpinRwLock<T>
}
impl <T> From<T> for RwLock<T> {
fn from(value: T) -> Self {
Self::new(value)
}
}
unsafe impl <T: ?Sized + Send> Send for RwLock<T> {
}
unsafe impl <T: ?Sized + Send> Sync for RwLock<T> {
}
impl <T> RwLock<T> {
pub const fn new(value: T) -> Self {
Self {
lock: SpinRwLock::new(value)
}
}
}
impl <T: ?Sized> RwLock<T> {
pub fn write(&self) -> Result<RwLockWriteGuard<'_, T>, PoisonError<T>> {
Ok(RwLockWriteGuard { guard: self.lock.write() })
}
pub fn read(&self) -> Result<RwLockReadGuard<'_, T>, PoisonError<T>> {
Ok(RwLockReadGuard { guard: self.lock.read() })
}
pub fn try_write(&self) -> Result<RwLockWriteGuard<'_, T>, TryLockError<T>> {
if let Some(guard) = self.lock.try_write() {
Ok(RwLockWriteGuard { guard })
} else {
Err(TryLockError::WouldBlock)
}
}
pub fn try_read(&self) -> Result<RwLockReadGuard<'_, T>, TryLockError<T>> {
if let Some(guard) = self.lock.try_read() {
Ok(RwLockReadGuard { guard })
} else {
Err(TryLockError::WouldBlock)
}
}
pub fn is_poisoned(&self) -> bool {
false
}
pub fn clear_poison(&self) {
}
pub fn into_inner(self) -> Result<T, PoisonError<T>> where T: Sized {
Ok(self.lock.into_inner())
}
pub fn get_mut(&mut self) -> Result<&mut T, PoisonError<T>> {
Ok(self.lock.get_mut())
}
}
#[derive(Debug)]
pub struct RwLockWriteGuard<'a, T: ?Sized> {
guard: spin::RwLockWriteGuard<'a, T>
}
impl <'a, T: Display> Display for RwLockWriteGuard<'a, T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", &*self.guard)
}
}
unsafe impl <'a, T: ?Sized + Send> Sync for RwLockWriteGuard<'a, T> {
}
impl <'a, T: ?Sized> !Send for RwLockWriteGuard<'a, T> {
}
impl <'a, T: ?Sized> Deref for RwLockWriteGuard<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&*self.guard
}
}
impl <'a, T: ?Sized> DerefMut for RwLockWriteGuard<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut *self.guard
}
}
#[derive(Debug)]
pub struct RwLockReadGuard<'a, T: ?Sized> {
guard: spin::RwLockReadGuard<'a, T>
}
impl <'a, T: Display> Display for RwLockReadGuard<'a, T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", &*self.guard)
}
}
unsafe impl <'a, T: ?Sized + Send> Sync for RwLockReadGuard<'a, T> {
}
impl <'a, T: ?Sized> !Send for RwLockReadGuard<'a, T> {
}
impl <'a, T: ?Sized> Deref for RwLockReadGuard<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&*self.guard
}
}