fp_library/classes/send_ref_functor_with_index.rs
1//! Thread-safe by-reference variant of [`FunctorWithIndex`](crate::classes::FunctorWithIndex).
2//!
3//! **User story:** "I want to map over a thread-safe memoized value by reference, with access to the index."
4//!
5//! ### Examples
6//!
7//! ```
8//! use fp_library::{
9//! brands::*,
10//! classes::send_ref_functor_with_index::SendRefFunctorWithIndex,
11//! types::*,
12//! };
13//!
14//! let lazy = ArcLazy::new(|| 42);
15//! let mapped = <LazyBrand<ArcLazyConfig> as SendRefFunctorWithIndex>::send_ref_map_with_index(
16//! |_, x: &i32| x.to_string(),
17//! &lazy,
18//! );
19//! assert_eq!(*mapped.evaluate(), "42");
20//! ```
21
22#[fp_macros::document_module]
23mod inner {
24 use {
25 crate::{
26 classes::*,
27 kinds::*,
28 },
29 fp_macros::*,
30 };
31
32 /// Thread-safe by-reference mapping with index over a structure.
33 ///
34 /// Similar to [`RefFunctorWithIndex`], but closures and elements must be `Send + Sync`.
35 #[kind(type Of<'a, A: 'a>: 'a;)]
36 pub trait SendRefFunctorWithIndex: SendRefFunctor + WithIndex {
37 /// Maps a function over the structure by reference with index (thread-safe).
38 #[document_signature]
39 #[document_type_parameters(
40 "The lifetime of the values.",
41 "The type of the elements.",
42 "The type of the result."
43 )]
44 #[document_parameters(
45 "The function to apply to each element's index and reference. Must be `Send + Sync`.",
46 "The structure to map over."
47 )]
48 #[document_returns("The mapped structure.")]
49 #[document_examples]
50 ///
51 /// ```
52 /// use fp_library::{
53 /// brands::*,
54 /// classes::send_ref_functor_with_index::SendRefFunctorWithIndex,
55 /// types::*,
56 /// };
57 ///
58 /// let lazy = ArcLazy::new(|| 42);
59 /// let mapped = <LazyBrand<ArcLazyConfig> as SendRefFunctorWithIndex>::send_ref_map_with_index(
60 /// |_, x: &i32| x.to_string(),
61 /// &lazy,
62 /// );
63 /// assert_eq!(*mapped.evaluate(), "42");
64 /// ```
65 fn send_ref_map_with_index<'a, A: Send + Sync + 'a, B: Send + Sync + 'a>(
66 f: impl Fn(Self::Index, &A) -> B + Send + Sync + 'a,
67 fa: &Self::Of<'a, A>,
68 ) -> Self::Of<'a, B>;
69 }
70
71 /// Maps a function over a structure by reference with index (thread-safe).
72 ///
73 /// Free function version that dispatches to [the type class' associated function][`SendRefFunctorWithIndex::send_ref_map_with_index`].
74 #[document_signature]
75 #[document_type_parameters(
76 "The lifetime of the values.",
77 "The brand of the structure.",
78 "The type of the elements.",
79 "The type of the result."
80 )]
81 #[document_parameters(
82 "The function to apply to each element's index and reference.",
83 "The structure to map over."
84 )]
85 #[document_returns("The mapped structure.")]
86 #[document_examples]
87 ///
88 /// ```
89 /// use fp_library::{
90 /// brands::*,
91 /// functions::*,
92 /// types::*,
93 /// };
94 ///
95 /// let lazy = ArcLazy::new(|| 42);
96 /// let mapped = send_ref_map_with_index::<LazyBrand<ArcLazyConfig>, _, _>(
97 /// |_, x: &i32| x.to_string(),
98 /// &lazy,
99 /// );
100 /// assert_eq!(*mapped.evaluate(), "42");
101 /// ```
102 pub fn send_ref_map_with_index<
103 'a,
104 Brand: SendRefFunctorWithIndex,
105 A: Send + Sync + 'a,
106 B: Send + Sync + 'a,
107 >(
108 f: impl Fn(Brand::Index, &A) -> B + Send + Sync + 'a,
109 fa: &Brand::Of<'a, A>,
110 ) -> Brand::Of<'a, B> {
111 Brand::send_ref_map_with_index(f, fa)
112 }
113}
114
115pub use inner::*;