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 ToDynCloneFn,
27 ToDynFn,
28 ToDynSendFn,
29 },
30 },
31 fp_macros::*,
32 std::sync::{
33 Arc,
34 Mutex,
35 },
36 };
37
38 impl Pointer for ArcBrand {
39 type Of<'a, T: ?Sized + 'a> = Arc<T>;
40
41 #[document_signature]
43 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
45 #[document_parameters("The value to wrap.")]
47 #[document_returns("The value wrapped in an `Arc`.")]
49 #[document_examples]
51 fn new<'a, T: 'a>(value: T) -> Arc<T> {
62 Arc::new(value)
63 }
64 }
65
66 impl RefCountedPointer for ArcBrand {
67 type Of<'a, T: ?Sized + 'a> = Arc<T>;
68 type TakeCellOf<'a, T: 'a> = Arc<Mutex<Option<T>>>;
69
70 #[document_signature]
72 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
74 #[document_parameters("The value to wrap.")]
76 #[document_returns("The value wrapped in an `Arc`.")]
78 #[document_examples]
80 fn new<'a, T: 'a>(value: T) -> Arc<T> {
91 Arc::new(value)
92 }
93
94 #[document_signature]
96 #[document_type_parameters(
98 "The lifetime of the wrapped value.",
99 "The type of the wrapped value."
100 )]
101 #[document_parameters("The pointer to attempt to unwrap.")]
103 #[document_returns("`Ok(value)` if this is the sole reference, otherwise `Err(ptr)`.")]
105 #[document_examples]
107 fn try_unwrap<'a, T: 'a>(ptr: Arc<T>) -> Result<T, Arc<T>> {
118 Arc::try_unwrap(ptr)
119 }
120
121 #[document_signature]
123 #[document_type_parameters("The lifetime of the value.", "The type of the value to store.")]
125 #[document_parameters("The value to store in the cell.")]
127 #[document_returns("A new `Arc<Mutex<Option<T>>>` containing the value.")]
129 #[document_examples]
131 fn take_cell_new<'a, T: 'a>(value: T) -> Arc<Mutex<Option<T>>> {
142 Arc::new(Mutex::new(Some(value)))
143 }
144
145 #[document_signature]
147 #[document_type_parameters("The lifetime of the value.", "The type of the stored value.")]
149 #[document_parameters("The cell to take the value from.")]
151 #[document_returns("`Some(value)` if the cell still contains a value, `None` otherwise.")]
153 #[document_examples]
155 fn take_cell_take<'a, T: 'a>(cell: &Arc<Mutex<Option<T>>>) -> Option<T> {
167 #[expect(
169 clippy::unwrap_used,
170 reason = "Lock only fails on poisoning, which cannot occur here"
171 )]
172 cell.lock().unwrap().take()
173 }
174 }
175
176 impl SendRefCountedPointer for ArcBrand {
177 type Of<'a, T: ?Sized + Send + Sync + 'a> = Arc<T>;
178
179 #[document_signature]
181 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
183 #[document_parameters("The value to wrap.")]
185 #[document_returns("The value wrapped in an `Arc`.")]
187 #[document_examples]
189 fn new<'a, T: Send + Sync + 'a>(value: T) -> Arc<T> {
200 Arc::new(value)
201 }
202 }
203
204 impl ToDynFn for ArcBrand {
205 #[document_signature]
207 #[document_type_parameters(
209 "The lifetime of the closure.",
210 "The input type of the function.",
211 "The output type of the function."
212 )]
213 #[document_parameters("The closure to coerce.")]
215 #[document_returns("The closure wrapped in an `Arc` as a trait object.")]
217 #[document_examples]
218 fn new<'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]
245 fn ref_new<'a, A: 'a, B: 'a>(f: impl 'a + Fn(&A) -> B) -> Arc<dyn 'a + Fn(&A) -> B> {
256 Arc::new(f)
257 }
258 }
259
260 impl ToDynCloneFn for ArcBrand {
261 #[document_signature]
263 #[document_type_parameters(
265 "The lifetime of the closure.",
266 "The input type of the function.",
267 "The output type of the function."
268 )]
269 #[document_parameters("The closure to coerce.")]
271 #[document_returns("The closure wrapped in an `Arc` as a trait object.")]
273 #[document_examples]
275 fn new<'a, A: 'a, B: 'a>(f: impl 'a + Fn(A) -> B) -> Arc<dyn 'a + Fn(A) -> B> {
286 Arc::new(f)
287 }
288
289 #[document_signature]
291 #[document_type_parameters(
293 "The lifetime of the closure.",
294 "The input type (the closure receives `&A`).",
295 "The output type of the function."
296 )]
297 #[document_parameters("The closure to coerce.")]
299 #[document_returns("The closure wrapped in an `Arc` as a by-reference trait object.")]
301 #[document_examples]
303 fn ref_new<'a, A: 'a, B: 'a>(f: impl 'a + Fn(&A) -> B) -> Arc<dyn 'a + Fn(&A) -> B> {
314 Arc::new(f)
315 }
316 }
317
318 impl ToDynSendFn for ArcBrand {
319 #[document_signature]
321 #[document_type_parameters(
323 "The lifetime of the closure.",
324 "The input type of the function.",
325 "The output type of the function."
326 )]
327 #[document_parameters("The closure to coerce.")]
329 #[document_returns("The closure wrapped in an `Arc` as a thread-safe trait object.")]
331 #[document_examples]
333 fn new<'a, A: 'a, B: 'a>(
344 f: impl 'a + Fn(A) -> B + Send + Sync
345 ) -> Arc<dyn 'a + Fn(A) -> B + Send + Sync> {
346 Arc::new(f)
347 }
348
349 #[document_signature]
351 #[document_type_parameters(
353 "The lifetime of the closure.",
354 "The input type (the closure receives `&A`).",
355 "The output type of the function."
356 )]
357 #[document_parameters("The closure to coerce.")]
359 #[document_returns(
361 "The closure wrapped in an `Arc` as a thread-safe by-reference trait object."
362 )]
363 #[document_examples]
365 fn ref_new<'a, A: 'a, B: 'a>(
376 f: impl 'a + Fn(&A) -> B + Send + Sync
377 ) -> Arc<dyn 'a + Fn(&A) -> B + Send + Sync> {
378 Arc::new(f)
379 }
380 }
381}
382
383#[cfg(test)]
384mod tests {
385 use crate::{
386 brands::ArcBrand,
387 classes::{
388 RefCountedPointer,
389 pointer::new as pointer_new,
390 ref_counted_pointer::new as ref_counted_pointer_new,
391 send_ref_counted_pointer::new as send_ref_counted_pointer_new,
392 },
393 };
394
395 #[test]
397 fn test_arc_pointer_new() {
398 let ptr = pointer_new::<ArcBrand, _>(42);
399 assert_eq!(*ptr, 42);
400 }
401
402 #[test]
404 fn test_arc_ref_counted_new() {
405 let ptr = ref_counted_pointer_new::<ArcBrand, _>(42);
406 assert_eq!(*ptr, 42);
407 }
408
409 #[test]
411 fn test_arc_send_ref_counted_new() {
412 let ptr = send_ref_counted_pointer_new::<ArcBrand, _>(42);
413 assert_eq!(*ptr, 42);
414 }
415
416 #[test]
418 fn test_arc_clone() {
419 let ptr = ref_counted_pointer_new::<ArcBrand, _>(42);
420 let clone = ptr.clone();
421 assert_eq!(*clone, 42);
422 }
423
424 #[test]
428 fn test_arc_try_unwrap() {
429 let ptr = ref_counted_pointer_new::<ArcBrand, _>(42);
430 assert_eq!(ArcBrand::try_unwrap(ptr), Ok(42));
431
432 let ptr = ref_counted_pointer_new::<ArcBrand, _>(42);
433 let _clone = ptr.clone();
434 assert!(ArcBrand::try_unwrap(ptr).is_err());
435 }
436}