fp_library/types/
arc_ptr.rs1#[fp_macros::document_module]
18mod inner {
19 use {
20 crate::{
21 brands::ArcBrand,
22 classes::{
23 Pointer,
24 RefCountedPointer,
25 SendRefCountedPointer,
26 SendUnsizedCoercible,
27 UnsizedCoercible,
28 },
29 },
30 fp_macros::*,
31 std::sync::{
32 Arc,
33 Mutex,
34 },
35 };
36
37 impl Pointer for ArcBrand {
38 type Of<'a, T: ?Sized + 'a> = Arc<T>;
39
40 #[document_signature]
42 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
44 #[document_parameters("The value to wrap.")]
46 #[document_returns("The value wrapped in an `Arc`.")]
48 #[document_examples]
50 fn new<'a, T: 'a>(value: T) -> Arc<T> {
61 Arc::new(value)
62 }
63 }
64
65 impl RefCountedPointer for ArcBrand {
66 type CloneableOf<'a, T: ?Sized + 'a> = Arc<T>;
67 type TakeCellOf<'a, T: 'a> = Arc<Mutex<Option<T>>>;
68
69 #[document_signature]
71 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
73 #[document_parameters("The value to wrap.")]
75 #[document_returns("The value wrapped in an `Arc`.")]
77 #[document_examples]
79 fn cloneable_new<'a, T: 'a>(value: T) -> Arc<T> {
90 Arc::new(value)
91 }
92
93 #[document_signature]
95 #[document_type_parameters(
97 "The lifetime of the wrapped value.",
98 "The type of the wrapped value."
99 )]
100 #[document_parameters("The pointer to attempt to unwrap.")]
102 #[document_returns("`Ok(value)` if this is the sole reference, otherwise `Err(ptr)`.")]
104 #[document_examples]
106 fn try_unwrap<'a, T: 'a>(ptr: Arc<T>) -> Result<T, Arc<T>> {
117 Arc::try_unwrap(ptr)
118 }
119
120 #[document_signature]
122 #[document_type_parameters("The lifetime of the value.", "The type of the value to store.")]
124 #[document_parameters("The value to store in the cell.")]
126 #[document_returns("A new `Arc<Mutex<Option<T>>>` containing the value.")]
128 #[document_examples]
130 fn take_cell_new<'a, T: 'a>(value: T) -> Arc<Mutex<Option<T>>> {
141 Arc::new(Mutex::new(Some(value)))
142 }
143
144 #[document_signature]
146 #[document_type_parameters("The lifetime of the value.", "The type of the stored value.")]
148 #[document_parameters("The cell to take the value from.")]
150 #[document_returns("`Some(value)` if the cell still contains a value, `None` otherwise.")]
152 #[document_examples]
154 fn take_cell_take<'a, T: 'a>(cell: &Arc<Mutex<Option<T>>>) -> Option<T> {
166 #[expect(
168 clippy::unwrap_used,
169 reason = "Lock only fails on poisoning, which cannot occur here"
170 )]
171 cell.lock().unwrap().take()
172 }
173 }
174
175 impl SendRefCountedPointer for ArcBrand {
176 type SendOf<'a, T: ?Sized + Send + Sync + 'a> = Arc<T>;
177
178 #[document_signature]
180 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
182 #[document_parameters("The value to wrap.")]
184 #[document_returns("The value wrapped in an `Arc`.")]
186 #[document_examples]
188 fn send_new<'a, T: Send + Sync + 'a>(value: T) -> Arc<T> {
199 Arc::new(value)
200 }
201 }
202
203 impl UnsizedCoercible for ArcBrand {
204 #[document_signature]
206 #[document_type_parameters(
208 "The lifetime of the closure.",
209 "The input type of the function.",
210 "The output type of the function."
211 )]
212 #[document_parameters("The closure to coerce.")]
214 #[document_returns("The closure wrapped in an `Arc` as a trait object.")]
216 #[document_examples]
218 fn coerce_fn<'a, A: 'a, B: 'a>(f: impl 'a + Fn(A) -> B) -> Arc<dyn 'a + Fn(A) -> B> {
229 Arc::new(f)
230 }
231
232 #[document_signature]
234 #[document_type_parameters(
236 "The lifetime of the closure.",
237 "The input type (the closure receives `&A`).",
238 "The output type of the function."
239 )]
240 #[document_parameters("The closure to coerce.")]
242 #[document_returns("The closure wrapped in an `Arc` as a by-reference trait object.")]
244 #[document_examples]
246 fn coerce_ref_fn<'a, A: 'a, B: 'a>(f: impl 'a + Fn(&A) -> B) -> Arc<dyn 'a + Fn(&A) -> B> {
257 Arc::new(f)
258 }
259 }
260
261 impl SendUnsizedCoercible for ArcBrand {
262 #[document_signature]
264 #[document_type_parameters(
266 "The lifetime of the closure.",
267 "The input type of the function.",
268 "The output type of the function."
269 )]
270 #[document_parameters("The closure to coerce.")]
272 #[document_returns("The closure wrapped in an `Arc` as a thread-safe trait object.")]
274 #[document_examples]
276 fn coerce_send_fn<'a, A: 'a, B: 'a>(
287 f: impl 'a + Fn(A) -> B + Send + Sync
288 ) -> Arc<dyn 'a + Fn(A) -> B + Send + Sync> {
289 Arc::new(f)
290 }
291
292 #[document_signature]
294 #[document_type_parameters(
296 "The lifetime of the closure.",
297 "The input type (the closure receives `&A`).",
298 "The output type of the function."
299 )]
300 #[document_parameters("The closure to coerce.")]
302 #[document_returns(
304 "The closure wrapped in an `Arc` as a thread-safe by-reference trait object."
305 )]
306 #[document_examples]
308 fn coerce_send_ref_fn<'a, A: 'a, B: 'a>(
319 f: impl 'a + Fn(&A) -> B + Send + Sync
320 ) -> Arc<dyn 'a + Fn(&A) -> B + Send + Sync> {
321 Arc::new(f)
322 }
323 }
324}
325
326#[cfg(test)]
327mod tests {
328 use crate::{
329 brands::ArcBrand,
330 classes::{
331 RefCountedPointer,
332 pointer::new,
333 ref_counted_pointer::cloneable_new,
334 send_ref_counted_pointer::send_new,
335 },
336 };
337
338 #[test]
340 fn test_arc_new() {
341 let ptr = new::<ArcBrand, _>(42);
342 assert_eq!(*ptr, 42);
343 }
344
345 #[test]
347 fn test_arc_cloneable_new() {
348 let ptr = cloneable_new::<ArcBrand, _>(42);
349 assert_eq!(*ptr, 42);
350 }
351
352 #[test]
354 fn test_arc_send_new() {
355 let ptr = send_new::<ArcBrand, _>(42);
356 assert_eq!(*ptr, 42);
357 }
358
359 #[test]
361 fn test_arc_clone() {
362 let ptr = cloneable_new::<ArcBrand, _>(42);
363 let clone = ptr.clone();
364 assert_eq!(*clone, 42);
365 }
366
367 #[test]
371 fn test_arc_try_unwrap() {
372 let ptr = cloneable_new::<ArcBrand, _>(42);
373 assert_eq!(ArcBrand::try_unwrap(ptr), Ok(42));
374
375 let ptr = cloneable_new::<ArcBrand, _>(42);
376 let _clone = ptr.clone();
377 assert!(ArcBrand::try_unwrap(ptr).is_err());
378 }
379}