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