fp_library/types/
rc_ptr.rs1#[fp_macros::document_module]
18mod inner {
19 use {
20 crate::{
21 brands::RcBrand,
22 classes::{
23 Pointer,
24 RefCountedPointer,
25 UnsizedCoercible,
26 },
27 },
28 fp_macros::*,
29 std::{
30 cell::RefCell,
31 rc::Rc,
32 },
33 };
34
35 impl Pointer for RcBrand {
36 type Of<'a, T: ?Sized + 'a> = Rc<T>;
37
38 #[document_signature]
40 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
42 #[document_parameters("The value to wrap.")]
44 #[document_returns("The value wrapped in an `Rc`.")]
46 #[document_examples]
48 fn new<'a, T: 'a>(value: T) -> Rc<T> {
59 Rc::new(value)
60 }
61 }
62
63 impl RefCountedPointer for RcBrand {
64 type CloneableOf<'a, T: ?Sized + 'a> = Rc<T>;
65 type TakeCellOf<'a, T: 'a> = Rc<RefCell<Option<T>>>;
66
67 #[document_signature]
69 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
71 #[document_parameters("The value to wrap.")]
73 #[document_returns("The value wrapped in an `Rc`.")]
75 #[document_examples]
77 fn cloneable_new<'a, T: 'a>(value: T) -> Rc<T> {
88 Rc::new(value)
89 }
90
91 #[document_signature]
93 #[document_type_parameters(
95 "The lifetime of the wrapped value.",
96 "The type of the wrapped value."
97 )]
98 #[document_parameters("The pointer to attempt to unwrap.")]
100 #[document_returns("`Ok(value)` if this is the sole reference, otherwise `Err(ptr)`.")]
102 #[document_examples]
104 fn try_unwrap<'a, T: 'a>(ptr: Rc<T>) -> Result<T, Rc<T>> {
115 Rc::try_unwrap(ptr)
116 }
117
118 #[document_signature]
120 #[document_type_parameters("The lifetime of the value.", "The type of the value to store.")]
122 #[document_parameters("The value to store in the cell.")]
124 #[document_returns("A new `Rc<RefCell<Option<T>>>` containing the value.")]
126 #[document_examples]
128 fn take_cell_new<'a, T: 'a>(value: T) -> Rc<RefCell<Option<T>>> {
139 Rc::new(RefCell::new(Some(value)))
140 }
141
142 #[document_signature]
144 #[document_type_parameters("The lifetime of the value.", "The type of the stored value.")]
146 #[document_parameters("The cell to take the value from.")]
148 #[document_returns("`Some(value)` if the cell still contains a value, `None` otherwise.")]
150 #[document_examples]
152 fn take_cell_take<'a, T: 'a>(cell: &Rc<RefCell<Option<T>>>) -> Option<T> {
164 cell.borrow_mut().take()
165 }
166 }
167
168 impl UnsizedCoercible for RcBrand {
169 #[document_signature]
171 #[document_type_parameters(
173 "The lifetime of the closure.",
174 "The input type of the function.",
175 "The output type of the function."
176 )]
177 #[document_parameters("The closure to coerce.")]
179 #[document_returns("The closure wrapped in an `Rc` as a trait object.")]
181 #[document_examples]
183 fn coerce_fn<'a, A: 'a, B: 'a>(f: impl 'a + Fn(A) -> B) -> Rc<dyn 'a + Fn(A) -> B> {
194 Rc::new(f)
195 }
196
197 #[document_signature]
199 #[document_type_parameters(
201 "The lifetime of the closure.",
202 "The input type (the closure receives `&A`).",
203 "The output type of the function."
204 )]
205 #[document_parameters("The closure to coerce.")]
207 #[document_returns("The closure wrapped in an `Rc` as a by-reference trait object.")]
209 #[document_examples]
211 fn coerce_ref_fn<'a, A: 'a, B: 'a>(f: impl 'a + Fn(&A) -> B) -> Rc<dyn 'a + Fn(&A) -> B> {
222 Rc::new(f)
223 }
224 }
225}
226
227#[cfg(test)]
228mod tests {
229
230 use crate::{
231 brands::RcBrand,
232 classes::{
233 RefCountedPointer,
234 pointer::new,
235 ref_counted_pointer::cloneable_new,
236 },
237 };
238
239 #[test]
241 fn test_rc_new() {
242 let ptr = new::<RcBrand, _>(42);
243 assert_eq!(*ptr, 42);
244 }
245
246 #[test]
248 fn test_rc_cloneable_new() {
249 let ptr = cloneable_new::<RcBrand, _>(42);
250 assert_eq!(*ptr, 42);
251 }
252
253 #[test]
255 fn test_rc_clone() {
256 let ptr = cloneable_new::<RcBrand, _>(42);
257 let clone = ptr.clone();
258 assert_eq!(*clone, 42);
259 }
260
261 #[test]
265 fn test_rc_try_unwrap() {
266 let ptr = cloneable_new::<RcBrand, _>(42);
267 assert_eq!(RcBrand::try_unwrap(ptr), Ok(42));
268
269 let ptr = cloneable_new::<RcBrand, _>(42);
270 let _clone = ptr.clone();
271 assert!(RcBrand::try_unwrap(ptr).is_err());
272 }
273}