use std::ops::{Deref, DerefMut};
use std::sync::Arc;
pub struct RwLock<T> {
inner: Arc<tokio::sync::RwLock<T>>,
}
impl<T> RwLock<T> {
pub fn new(value: T) -> Self {
Self {
inner: Arc::new(tokio::sync::RwLock::new(value)),
}
}
pub async fn read(&self) -> RwLockReadGuard<'_, T> {
RwLockReadGuard {
inner: self.inner.read().await,
}
}
pub async fn write(&self) -> RwLockWriteGuard<'_, T> {
RwLockWriteGuard {
inner: self.inner.write().await,
}
}
pub async fn read_owned(self: Arc<Self>) -> OwnedRwLockReadGuard<T> {
OwnedRwLockReadGuard {
inner: Arc::clone(&self.inner).read_owned().await,
}
}
pub async fn write_owned(self: Arc<Self>) -> OwnedRwLockWriteGuard<T> {
OwnedRwLockWriteGuard {
inner: Arc::clone(&self.inner).write_owned().await,
}
}
pub fn blocking_read(&self) -> RwLockReadGuard<'_, T> {
RwLockReadGuard {
inner: self.inner.blocking_read(),
}
}
pub fn blocking_write(&self) -> RwLockWriteGuard<'_, T> {
RwLockWriteGuard {
inner: self.inner.blocking_write(),
}
}
pub fn try_read_owned(self: Arc<Self>) -> Result<OwnedRwLockReadGuard<T>, RwLockTryLockError> {
Arc::clone(&self.inner)
.try_read_owned()
.map(|inner| OwnedRwLockReadGuard { inner })
.map_err(|_| RwLockTryLockError)
}
pub fn into_inner(self) -> Option<T> {
Arc::into_inner(self.inner).map(tokio::sync::RwLock::into_inner)
}
}
impl<T: Default> Default for RwLock<T> {
fn default() -> Self {
Self::new(T::default())
}
}
impl<T> std::fmt::Debug for RwLock<T> {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.debug_struct("RwLock").finish_non_exhaustive()
}
}
pub struct RwLockReadGuard<'a, T> {
inner: tokio::sync::RwLockReadGuard<'a, T>,
}
impl<T> Deref for RwLockReadGuard<'_, T> {
type Target = T;
fn deref(&self) -> &T {
&self.inner
}
}
pub struct RwLockWriteGuard<'a, T> {
inner: tokio::sync::RwLockWriteGuard<'a, T>,
}
impl<T> Deref for RwLockWriteGuard<'_, T> {
type Target = T;
fn deref(&self) -> &T {
&self.inner
}
}
impl<T> DerefMut for RwLockWriteGuard<'_, T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.inner
}
}
pub struct OwnedRwLockReadGuard<T> {
inner: tokio::sync::OwnedRwLockReadGuard<T>,
}
impl<T> Deref for OwnedRwLockReadGuard<T> {
type Target = T;
fn deref(&self) -> &T {
&self.inner
}
}
pub struct OwnedRwLockWriteGuard<T> {
inner: tokio::sync::OwnedRwLockWriteGuard<T>,
}
impl<T> Deref for OwnedRwLockWriteGuard<T> {
type Target = T;
fn deref(&self) -> &T {
&self.inner
}
}
impl<T> DerefMut for OwnedRwLockWriteGuard<T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.inner
}
}
macro_rules! debug_guard {
($($guard:ident$(<$lifetime:lifetime>)?),+) => {$(
impl<T: std::fmt::Debug> std::fmt::Debug for $guard<$($lifetime,)? T> {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(&**self, formatter)
}
}
)+};
}
debug_guard!(
RwLockReadGuard<'_>,
RwLockWriteGuard<'_>,
OwnedRwLockReadGuard,
OwnedRwLockWriteGuard
);
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct RwLockTryLockError;
impl std::fmt::Display for RwLockTryLockError {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("rwlock is busy")
}
}
impl std::error::Error for RwLockTryLockError {}