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}