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