fp_library/classes/
thunk_wrapper.rs

1//! A trait for pointers that can wrap a thunk with interior mutability.
2//!
3//! ### Examples
4//!
5//! ```
6//! use fp_library::{brands::*, functions::*};
7//!
8//! let cell = thunk_wrapper_new::<RcBrand, _>(Some(42));
9//! assert_eq!(thunk_wrapper_take::<RcBrand, _>(&cell), Some(42));
10//! ```
11
12/// Trait for pointers that can wrap a thunk with interior mutability.
13///
14/// This is used by `Lazy` to store the thunk and clear it after execution.
15pub trait ThunkWrapper {
16	/// The cell type used to store the thunk.
17	type Cell<T>;
18
19	/// Creates a new cell containing the value.
20	///
21	/// ### Type Signature
22	///
23	/// `forall a. Option a -> Cell a`
24	///
25	/// ### Type Parameters
26	///
27	/// * `T`: The type of the value.
28	///
29	/// ### Parameters
30	///
31	/// * `value`: The value to wrap.
32	///
33	/// ### Returns
34	///
35	/// A new cell containing the value.
36	///
37	/// ### Examples
38	///
39	/// ```
40	/// use fp_library::{brands::*, functions::*};
41	///
42	/// let cell = thunk_wrapper_new::<RcBrand, _>(Some(42));
43	/// assert_eq!(thunk_wrapper_take::<RcBrand, _>(&cell), Some(42));
44	/// ```
45	fn new<T>(value: Option<T>) -> Self::Cell<T>;
46
47	/// Takes the value out of the cell.
48	///
49	/// ### Type Signature
50	///
51	/// `forall a. Cell a -> Option a`
52	///
53	/// ### Type Parameters
54	///
55	/// * `T`: The type of the value.
56	///
57	/// ### Parameters
58	///
59	/// * `cell`: The cell to take the value from.
60	///
61	/// ### Returns
62	///
63	/// The value if it was present, or `None`.
64	///
65	/// ### Examples
66	///
67	/// ```
68	/// use fp_library::{brands::*, functions::*};
69	///
70	/// let cell = thunk_wrapper_new::<RcBrand, _>(Some(42));
71	/// assert_eq!(thunk_wrapper_take::<RcBrand, _>(&cell), Some(42));
72	/// assert_eq!(thunk_wrapper_take::<RcBrand, _>(&cell), None);
73	/// ```
74	fn take<T>(cell: &Self::Cell<T>) -> Option<T>;
75}
76
77/// Creates a new cell containing the value.
78///
79/// Free function version that dispatches to [the type class' associated function][`ThunkWrapper::new`].
80///
81/// ### Type Signature
82///
83/// `forall a. Option a -> Cell a`
84///
85/// ### Type Parameters
86///
87/// * `Brand`: The pointer brand.
88/// * `T`: The type of the value.
89///
90/// ### Parameters
91///
92/// * `value`: The value to wrap.
93///
94/// ### Returns
95///
96/// A new cell containing the value.
97///
98/// ### Examples
99///
100/// ```
101/// use fp_library::{brands::*, functions::*};
102///
103/// let cell = thunk_wrapper_new::<RcBrand, _>(Some(42));
104/// assert_eq!(thunk_wrapper_take::<RcBrand, _>(&cell), Some(42));
105/// ```
106pub fn new<Brand: ThunkWrapper, T>(value: Option<T>) -> Brand::Cell<T> {
107	Brand::new(value)
108}
109
110/// Takes the value out of the cell.
111///
112/// Free function version that dispatches to [the type class' associated function][`ThunkWrapper::take`].
113///
114/// ### Type Signature
115///
116/// `forall a. Cell a -> Option a`
117///
118/// ### Type Parameters
119///
120/// * `Brand`: The pointer brand.
121/// * `T`: The type of the value.
122///
123/// ### Parameters
124///
125/// * `cell`: The cell to take the value from.
126///
127/// ### Returns
128///
129/// The value if it was present, or `None`.
130///
131/// ### Examples
132///
133/// ```
134/// use fp_library::{brands::*, functions::*};
135///
136/// let cell = thunk_wrapper_new::<RcBrand, _>(Some(42));
137/// assert_eq!(thunk_wrapper_take::<RcBrand, _>(&cell), Some(42));
138/// assert_eq!(thunk_wrapper_take::<RcBrand, _>(&cell), None);
139/// ```
140pub fn take<Brand: ThunkWrapper, T>(cell: &Brand::Cell<T>) -> Option<T> {
141	Brand::take(cell)
142}