fp_library/classes/send_ref_pointed.rs
1//! Thread-safe by-ref value injection with [`send_ref_pure`].
2//!
3//! Like [`RefPointed::ref_pure`](crate::classes::RefPointed::ref_pure), but
4//! requires `A: Send + Sync + Clone` so the result can cross thread boundaries.
5//!
6//! ### Examples
7//!
8//! ```
9//! use fp_library::{
10//! brands::*,
11//! classes::*,
12//! functions::*,
13//! types::*,
14//! };
15//!
16//! let value = 42;
17//! let lazy = send_ref_pure::<LazyBrand<ArcLazyConfig>, _>(&value);
18//! assert_eq!(*lazy.evaluate(), 42);
19//! ```
20
21#[fp_macros::document_module]
22mod inner {
23 use {
24 crate::kinds::*,
25 fp_macros::*,
26 };
27
28 /// A type class for injecting a value into a context from a reference,
29 /// with `Send + Sync` bounds.
30 ///
31 /// This is the thread-safe counterpart of [`RefPointed`](crate::classes::RefPointed).
32 #[kind(type Of<'a, A: 'a>: 'a;)]
33 pub trait SendRefPointed {
34 /// Wraps a cloned value in a new thread-safe memoized context.
35 #[document_signature]
36 ///
37 #[document_type_parameters(
38 "The lifetime of the value.",
39 "The type of the value. Must be `Clone + Send + Sync`."
40 )]
41 ///
42 #[document_parameters("A reference to the value to wrap.")]
43 ///
44 #[document_returns("A new thread-safe memoized value containing a clone of the input.")]
45 #[document_examples]
46 ///
47 /// ```
48 /// use fp_library::{
49 /// brands::*,
50 /// classes::*,
51 /// types::*,
52 /// };
53 ///
54 /// let value = 42;
55 /// let lazy = LazyBrand::<ArcLazyConfig>::send_ref_pure(&value);
56 /// assert_eq!(*lazy.evaluate(), 42);
57 /// ```
58 fn send_ref_pure<'a, A: Clone + Send + Sync + 'a>(
59 a: &A
60 ) -> Apply!(<Self as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>);
61 }
62
63 /// Wraps a cloned value in a new thread-safe memoized context.
64 ///
65 /// Free function version that dispatches to [the type class' associated function][`SendRefPointed::send_ref_pure`].
66 #[document_signature]
67 ///
68 #[document_type_parameters(
69 "The lifetime of the value.",
70 "The brand of the context.",
71 "The type of the value. Must be `Clone + Send + Sync`."
72 )]
73 ///
74 #[document_parameters("A reference to the value to wrap.")]
75 ///
76 #[document_returns("A new thread-safe memoized value containing a clone of the input.")]
77 #[document_examples]
78 ///
79 /// ```
80 /// use fp_library::{
81 /// brands::*,
82 /// functions::*,
83 /// types::*,
84 /// };
85 ///
86 /// let value = 42;
87 /// let lazy = send_ref_pure::<LazyBrand<ArcLazyConfig>, _>(&value);
88 /// assert_eq!(*lazy.evaluate(), 42);
89 /// ```
90 pub fn send_ref_pure<'a, Brand: SendRefPointed, A: Clone + Send + Sync + 'a>(
91 a: &A
92 ) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
93 Brand::send_ref_pure(a)
94 }
95}
96
97pub use inner::*;