Skip to main content

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::*;