async_handle/
lib.rs

1use async_rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
2use std::{
3    fmt::{Debug, Display, Formatter},
4    sync::Arc,
5};
6
7// RwLock ensures this safeness for us
8unsafe impl<T: Send + ?Sized> Send for Handle<T> {}
9unsafe impl<T: Send + Sync + ?Sized> Sync for Handle<T> {}
10
11/// Reference-counted async RwLock
12pub struct Handle<T: ?Sized> {
13    data: Arc<RwLock<T>>,
14}
15
16impl<T> Handle<T> {
17    /// Creates a new handle wrapping `value`
18    pub fn new(value: T) -> Self {
19        Self {
20            data: Arc::new(RwLock::new(value)),
21        }
22    }
23
24    /// Lock the contained value for reading
25    pub async fn read(&self) -> RwLockReadGuard<'_, T> {
26        self.data.read().await
27    }
28
29    /// Lock the contained value for writing
30    pub async fn write(&self) -> RwLockWriteGuard<'_, T> {
31        self.data.write().await
32    }
33
34    pub fn try_unwrap(self) -> Result<T, Self> {
35        match Arc::try_unwrap(self.data) {
36            Ok(lock) => Ok(lock.into_inner()),
37            Err(data) => Err(Self { data }),
38        }
39    }
40
41    /// Returns true if the two Handles point to the same allocation (in a vein similar to Arc::ptr_eq).
42    pub fn ptr_eq(this: &Self, other: &Self) -> bool {
43        Arc::ptr_eq(&this.data, &other.data)
44    }
45}
46
47impl<T: ?Sized> Clone for Handle<T> {
48    fn clone(&self) -> Self {
49        Self {
50            data: self.data.clone(),
51        }
52    }
53}
54
55impl<T> Handle<T>
56where
57    T: Clone,
58{
59    /// Returns a new Handle with a clone of the value within
60    pub async fn cloned(&self) -> Self {
61        let data = self.data.read().await;
62        Self::new(data.clone())
63    }
64}
65
66impl<T> Debug for Handle<T>
67where
68    T: Debug,
69{
70    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
71        futures_lite::future::block_on(async {
72            let data = self.read().await;
73            data.fmt(f)
74        })
75    }
76}
77
78impl<T> Display for Handle<T>
79where
80    T: Display,
81{
82    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
83        futures_lite::future::block_on(async {
84            let data = self.read().await;
85            data.fmt(f)
86        })
87    }
88}
89
90impl<T> Default for Handle<T>
91where
92    T: Default,
93{
94    fn default() -> Self {
95        Self::new(T::default())
96    }
97}