1use std::fmt;
2use std::ops::{Deref, DerefMut};
3
4pub struct Lock<T> {
8 #[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
9 inner: std::sync::Arc<parking_lot::Mutex<T>>,
10
11 #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
12 inner: std::rc::Rc<std::cell::RefCell<T>>,
13}
14
15#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
16impl<T> Lock<T> {
17 pub fn new(value: T) -> Self {
18 Self {
19 inner: std::sync::Arc::new(parking_lot::Mutex::new(value)),
20 }
21 }
22
23 pub fn is_clone(&self, other: &Self) -> bool {
24 std::sync::Arc::ptr_eq(&self.inner, &other.inner)
25 }
26}
27
28impl<T> Lock<T> {
29 pub fn lock(&self) -> LockGuard<'_, T> {
30 LockGuard::new(&self.inner)
31 }
32
33 pub fn downgrade(&self) -> LockWeak<T> {
34 LockWeak::new(&self.inner)
35 }
36}
37
38#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
39impl<T> Lock<T> {
40 pub fn new(value: T) -> Self {
41 Self {
42 inner: std::rc::Rc::new(std::cell::RefCell::new(value)),
43 }
44 }
45
46 pub fn is_clone(&self, other: &Self) -> bool {
47 std::rc::Rc::ptr_eq(&self.inner, &other.inner)
48 }
49}
50
51impl<T: Default> Default for Lock<T> {
52 fn default() -> Self {
53 Self::new(T::default())
54 }
55}
56
57impl<T> Clone for Lock<T> {
58 fn clone(&self) -> Self {
59 Self {
60 inner: self.inner.clone(),
61 }
62 }
63}
64
65impl<T: fmt::Debug> fmt::Debug for Lock<T> {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 self.inner.fmt(f)
68 }
69}
70
71pub struct LockGuard<'a, T> {
72 #[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
73 inner: parking_lot::MutexGuard<'a, T>,
74
75 #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
76 inner: std::cell::RefMut<'a, T>,
77}
78
79#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
80impl<'a, T> LockGuard<'a, T> {
81 fn new(inner: &'a std::sync::Arc<parking_lot::Mutex<T>>) -> Self {
82 Self { inner: inner.lock() }
83 }
84}
85
86#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
87impl<'a, T> LockGuard<'a, T> {
88 fn new(inner: &'a std::rc::Rc<std::cell::RefCell<T>>) -> Self {
89 Self {
90 inner: inner.borrow_mut(),
91 }
92 }
93}
94
95impl<T> Deref for LockGuard<'_, T> {
96 type Target = T;
97
98 fn deref(&self) -> &Self::Target {
99 &self.inner
100 }
101}
102
103impl<T> DerefMut for LockGuard<'_, T> {
104 fn deref_mut(&mut self) -> &mut Self::Target {
105 &mut self.inner
106 }
107}
108
109impl<T: fmt::Debug> fmt::Debug for LockGuard<'_, T> {
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 self.inner.fmt(f)
112 }
113}
114
115pub struct LockWeak<T> {
116 #[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
117 inner: std::sync::Weak<parking_lot::Mutex<T>>,
118
119 #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
120 inner: std::rc::Weak<std::cell::RefCell<T>>,
121}
122
123#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
124impl<T> LockWeak<T> {
125 fn new(inner: &std::sync::Arc<parking_lot::Mutex<T>>) -> Self {
126 Self {
127 inner: std::sync::Arc::downgrade(inner),
128 }
129 }
130}
131
132#[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))]
133impl<T> LockWeak<T> {
134 fn new(inner: &std::rc::Rc<std::cell::RefCell<T>>) -> Self {
135 Self {
136 inner: std::rc::Rc::downgrade(inner),
137 }
138 }
139}
140
141impl<T> LockWeak<T> {
142 pub fn upgrade(&self) -> Option<Lock<T>> {
143 Some(Lock {
144 inner: self.inner.upgrade()?,
145 })
146 }
147}
148
149impl<T> Clone for LockWeak<T> {
150 fn clone(&self) -> Self {
151 Self {
152 inner: self.inner.clone(),
153 }
154 }
155}