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 ToDynCloneFn,
26 ToDynFn,
27 },
28 },
29 fp_macros::*,
30 std::{
31 cell::RefCell,
32 rc::Rc,
33 },
34 };
35
36 impl Pointer for RcBrand {
37 type Of<'a, T: ?Sized + 'a> = Rc<T>;
38
39 #[document_signature]
41 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
43 #[document_parameters("The value to wrap.")]
45 #[document_returns("The value wrapped in an `Rc`.")]
47 #[document_examples]
49 fn new<'a, T: 'a>(value: T) -> Rc<T> {
60 Rc::new(value)
61 }
62 }
63
64 impl RefCountedPointer for RcBrand {
65 type Of<'a, T: ?Sized + 'a> = Rc<T>;
66 type TakeCellOf<'a, T: 'a> = Rc<RefCell<Option<T>>>;
67
68 #[document_signature]
70 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
72 #[document_parameters("The value to wrap.")]
74 #[document_returns("The value wrapped in an `Rc`.")]
76 #[document_examples]
78 fn new<'a, T: 'a>(value: T) -> Rc<T> {
89 Rc::new(value)
90 }
91
92 #[document_signature]
94 #[document_type_parameters(
96 "The lifetime of the wrapped value.",
97 "The type of the wrapped value."
98 )]
99 #[document_parameters("The pointer to attempt to unwrap.")]
101 #[document_returns("`Ok(value)` if this is the sole reference, otherwise `Err(ptr)`.")]
103 #[document_examples]
105 fn try_unwrap<'a, T: 'a>(ptr: Rc<T>) -> Result<T, Rc<T>> {
116 Rc::try_unwrap(ptr)
117 }
118
119 #[document_signature]
121 #[document_type_parameters("The lifetime of the value.", "The type of the value to store.")]
123 #[document_parameters("The value to store in the cell.")]
125 #[document_returns("A new `Rc<RefCell<Option<T>>>` containing the value.")]
127 #[document_examples]
129 fn take_cell_new<'a, T: 'a>(value: T) -> Rc<RefCell<Option<T>>> {
140 Rc::new(RefCell::new(Some(value)))
141 }
142
143 #[document_signature]
145 #[document_type_parameters("The lifetime of the value.", "The type of the stored value.")]
147 #[document_parameters("The cell to take the value from.")]
149 #[document_returns("`Some(value)` if the cell still contains a value, `None` otherwise.")]
151 #[document_examples]
153 fn take_cell_take<'a, T: 'a>(cell: &Rc<RefCell<Option<T>>>) -> Option<T> {
165 cell.borrow_mut().take()
166 }
167 }
168
169 impl ToDynFn for RcBrand {
170 #[document_signature]
172 #[document_type_parameters(
174 "The lifetime of the closure.",
175 "The input type of the function.",
176 "The output type of the function."
177 )]
178 #[document_parameters("The closure to coerce.")]
180 #[document_returns("The closure wrapped in an `Rc` as a trait object.")]
182 #[document_examples]
183 fn new<'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]
210 fn ref_new<'a, A: 'a, B: 'a>(f: impl 'a + Fn(&A) -> B) -> Rc<dyn 'a + Fn(&A) -> B> {
221 Rc::new(f)
222 }
223 }
224
225 impl ToDynCloneFn for RcBrand {
226 #[document_signature]
228 #[document_type_parameters(
230 "The lifetime of the closure.",
231 "The input type of the function.",
232 "The output type of the function."
233 )]
234 #[document_parameters("The closure to coerce.")]
236 #[document_returns("The closure wrapped in an `Rc` as a trait object.")]
238 #[document_examples]
240 fn new<'a, A: 'a, B: 'a>(f: impl 'a + Fn(A) -> B) -> Rc<dyn 'a + Fn(A) -> B> {
251 Rc::new(f)
252 }
253
254 #[document_signature]
256 #[document_type_parameters(
258 "The lifetime of the closure.",
259 "The input type (the closure receives `&A`).",
260 "The output type of the function."
261 )]
262 #[document_parameters("The closure to coerce.")]
264 #[document_returns("The closure wrapped in an `Rc` as a by-reference trait object.")]
266 #[document_examples]
268 fn ref_new<'a, A: 'a, B: 'a>(f: impl 'a + Fn(&A) -> B) -> Rc<dyn 'a + Fn(&A) -> B> {
279 Rc::new(f)
280 }
281 }
282}
283
284#[cfg(test)]
285mod tests {
286
287 use crate::{
288 brands::RcBrand,
289 classes::{
290 RefCountedPointer,
291 pointer::new as pointer_new,
292 ref_counted_pointer::new as ref_counted_pointer_new,
293 },
294 };
295
296 #[test]
298 fn test_rc_pointer_new() {
299 let ptr = pointer_new::<RcBrand, _>(42);
300 assert_eq!(*ptr, 42);
301 }
302
303 #[test]
305 fn test_rc_ref_counted_new() {
306 let ptr = ref_counted_pointer_new::<RcBrand, _>(42);
307 assert_eq!(*ptr, 42);
308 }
309
310 #[test]
312 fn test_rc_clone() {
313 let ptr = ref_counted_pointer_new::<RcBrand, _>(42);
314 let clone = ptr.clone();
315 assert_eq!(*clone, 42);
316 }
317
318 #[test]
322 fn test_rc_try_unwrap() {
323 let ptr = ref_counted_pointer_new::<RcBrand, _>(42);
324 assert_eq!(RcBrand::try_unwrap(ptr), Ok(42));
325
326 let ptr = ref_counted_pointer_new::<RcBrand, _>(42);
327 let _clone = ptr.clone();
328 assert!(RcBrand::try_unwrap(ptr).is_err());
329 }
330}