1use std::sync::Arc;
5
6pub use serde_json::from_str as deserialize_field;
8pub use serde_json::to_string as serialize_field;
10
11pub trait PersistentField<'a, T>: Send + Sync
19where
20 T: serde::Serialize + serde::Deserialize<'a>,
21{
22 fn set(&self, new_value: T);
24
25 fn map<F, R>(&self, f: F) -> R
28 where
29 F: Fn(&T) -> R;
30}
31
32macro_rules! impl_persistent_arc {
35 ($ty:ty, T) => {
36 impl<'a, T> PersistentField<'a, T> for Arc<$ty>
37 where
38 T: serde::Serialize + serde::Deserialize<'a> + Send + Sync,
39 {
40 fn set(&self, new_value: T) {
41 PersistentField::set(self.as_ref(), new_value);
42 }
43 fn map<F, R>(&self, f: F) -> R
44 where
45 F: Fn(&T) -> R,
46 {
47 self.as_ref().map(f)
48 }
49 }
50 };
51
52 ($ty:ty, T: $($bounds:tt)*) => {
53 impl<'a, T> PersistentField<'a, T> for Arc<$ty>
54 where
55 T: $($bounds)*,
56 {
57 fn set(&self, new_value: T) {
58 self.as_ref().set(new_value);
59 }
60 fn map<F, R>(&self, f: F) -> R
61 where
62 F: Fn(&T) -> R,
63 {
64 self.as_ref().map(f)
65 }
66 }
67 };
68 ($ty:ty, $inner_ty:ty) => {
69 impl<'a> PersistentField<'a, $inner_ty> for Arc<$ty> {
70 fn set(&self, new_value: $inner_ty) {
71 self.as_ref().set(new_value);
72 }
73 fn map<F, R>(&self, f: F) -> R
74 where
75 F: Fn(&$inner_ty) -> R,
76 {
77 self.as_ref().map(f)
78 }
79 }
80 };
81}
82
83impl<'a, T> PersistentField<'a, T> for std::sync::RwLock<T>
84where
85 T: serde::Serialize + serde::Deserialize<'a> + Send + Sync,
86{
87 fn set(&self, new_value: T) {
88 *self.write().expect("Poisoned RwLock on write") = new_value;
89 }
90 fn map<F, R>(&self, f: F) -> R
91 where
92 F: Fn(&T) -> R,
93 {
94 f(&self.read().expect("Poisoned RwLock on read"))
95 }
96}
97impl_persistent_arc!(std::sync::RwLock<T>, T);
98
99impl<'a, T> PersistentField<'a, T> for parking_lot::RwLock<T>
100where
101 T: serde::Serialize + serde::Deserialize<'a> + Send + Sync,
102{
103 fn set(&self, new_value: T) {
104 *self.write() = new_value;
105 }
106 fn map<F, R>(&self, f: F) -> R
107 where
108 F: Fn(&T) -> R,
109 {
110 f(&self.read())
111 }
112}
113impl_persistent_arc!(parking_lot::RwLock<T>, T);
114
115impl<'a, T> PersistentField<'a, T> for std::sync::Mutex<T>
116where
117 T: serde::Serialize + serde::Deserialize<'a> + Send + Sync,
118{
119 fn set(&self, new_value: T) {
120 *self.lock().expect("Poisoned Mutex") = new_value;
121 }
122 fn map<F, R>(&self, f: F) -> R
123 where
124 F: Fn(&T) -> R,
125 {
126 f(&self.lock().expect("Poisoned Mutex"))
127 }
128}
129impl_persistent_arc!(std::sync::Mutex<T>, T);
130
131impl<'a, T> PersistentField<'a, T> for atomic_refcell::AtomicRefCell<T>
132where
133 T: serde::Serialize + serde::Deserialize<'a> + Send + Sync,
134{
135 fn set(&self, new_value: T) {
136 *self.borrow_mut() = new_value;
137 }
138 fn map<F, R>(&self, f: F) -> R
139 where
140 F: Fn(&T) -> R,
141 {
142 f(&self.borrow())
143 }
144}
145impl_persistent_arc!(atomic_refcell::AtomicRefCell<T>, T);
146
147macro_rules! impl_persistent_field_parking_lot_mutex {
148 ($ty:ty) => {
149 impl<'a, T> PersistentField<'a, T> for $ty
150 where
151 T: serde::Serialize + serde::Deserialize<'a> + Send + Sync,
152 {
153 fn set(&self, new_value: T) {
154 *self.lock() = new_value;
155 }
156 fn map<F, R>(&self, f: F) -> R
157 where
158 F: Fn(&T) -> R,
159 {
160 f(&self.lock())
161 }
162 }
163
164 impl_persistent_arc!($ty, T);
165 };
166}
167
168impl_persistent_field_parking_lot_mutex!(parking_lot::Mutex<T>);
169impl_persistent_field_parking_lot_mutex!(parking_lot::FairMutex<T>);
170
171macro_rules! impl_persistent_atomic {
172 ($ty:ty, $inner_ty:ty) => {
173 impl PersistentField<'_, $inner_ty> for $ty {
174 fn set(&self, new_value: $inner_ty) {
175 self.store(new_value, std::sync::atomic::Ordering::SeqCst);
176 }
177 fn map<F, R>(&self, f: F) -> R
178 where
179 F: Fn(&$inner_ty) -> R,
180 {
181 f(&self.load(std::sync::atomic::Ordering::SeqCst))
182 }
183 }
184
185 impl_persistent_arc!($ty, $inner_ty);
186 };
187}
188
189impl_persistent_atomic!(std::sync::atomic::AtomicBool, bool);
190impl_persistent_atomic!(std::sync::atomic::AtomicI8, i8);
191impl_persistent_atomic!(std::sync::atomic::AtomicI16, i16);
192impl_persistent_atomic!(std::sync::atomic::AtomicI32, i32);
193impl_persistent_atomic!(std::sync::atomic::AtomicI64, i64);
194impl_persistent_atomic!(std::sync::atomic::AtomicIsize, isize);
195impl_persistent_atomic!(std::sync::atomic::AtomicU8, u8);
196impl_persistent_atomic!(std::sync::atomic::AtomicU16, u16);
197impl_persistent_atomic!(std::sync::atomic::AtomicU32, u32);
198impl_persistent_atomic!(std::sync::atomic::AtomicU64, u64);
199impl_persistent_atomic!(std::sync::atomic::AtomicUsize, usize);
200impl_persistent_atomic!(atomic_float::AtomicF32, f32);
201impl_persistent_atomic!(atomic_float::AtomicF64, f64);
202
203impl<'a, T> PersistentField<'a, T> for crossbeam_utils::atomic::AtomicCell<T>
204where
205 T: serde::Serialize + serde::Deserialize<'a> + Copy + Send,
206{
207 fn set(&self, new_value: T) {
208 self.store(new_value);
209 }
210 fn map<F, R>(&self, f: F) -> R
211 where
212 F: Fn(&T) -> R,
213 {
214 f(&self.load())
215 }
216}
217impl_persistent_arc!(crossbeam_utils::atomic::AtomicCell<T>,
218 T: serde::Serialize + serde::Deserialize<'a> + Copy + Send);
219
220pub mod serialize_atomic_cell {
223 use crossbeam_utils::atomic::AtomicCell;
224 use serde::{Deserialize, Deserializer, Serialize, Serializer};
225
226 pub fn serialize<S, T>(cell: &AtomicCell<T>, serializer: S) -> Result<S::Ok, S::Error>
227 where
228 S: Serializer,
229 T: Serialize + Copy,
230 {
231 cell.load().serialize(serializer)
232 }
233
234 pub fn deserialize<'de, D, T>(deserializer: D) -> Result<AtomicCell<T>, D::Error>
235 where
236 D: Deserializer<'de>,
237 T: Deserialize<'de> + Copy,
238 {
239 T::deserialize(deserializer).map(AtomicCell::new)
240 }
241}