fp_library/classes/pointer.rs
1//! Hierarchy of traits for abstracting over different types of pointers and their capabilities.
2//!
3//! The hierarchy is as follows:
4//! * [`Pointer`]: Base trait for any heap-allocated pointer.
5//! * [`RefCountedPointer`][super::ref_counted_pointer::RefCountedPointer]: Extension for pointers that allow shared ownership (cloning).
6//! * [`SendRefCountedPointer`][super::send_ref_counted_pointer::SendRefCountedPointer]: Extension for thread-safe reference-counted pointers.
7//!
8//! Additionally, [`UnsizedCoercible`][super::unsized_coercible::UnsizedCoercible] and [`SendUnsizedCoercible`][super::send_unsized_coercible::SendUnsizedCoercible] are provided to support
9//! coercing sized closures into trait objects (`dyn Fn`).
10//!
11//! ### Examples
12//!
13//! ```
14//! use fp_library::{
15//! brands::*,
16//! functions::*,
17//! };
18//!
19//! let ptr = pointer_new::<RcBrand, _>(42);
20//! assert_eq!(*ptr, 42);
21//! ```
22
23#[fp_macros::document_module]
24mod inner {
25 use {
26 fp_macros::*,
27 std::ops::Deref,
28 };
29
30 /// Base type class for heap-allocated pointers.
31 ///
32 /// This is the minimal abstraction: any type that can wrap a value and
33 /// dereference to it. Does NOT require Clone - that's added by subtraits.
34 ///
35 /// By explicitly requiring that the type parameter `T` outlives the application lifetime `'a`,
36 /// we provide the compiler with the necessary guarantees to handle trait objects
37 /// (like `dyn Fn`) commonly used in pointer implementations. This resolves potential
38 /// E0310 errors where the compiler cannot otherwise prove that captured variables in
39 /// closures satisfy the required lifetime bounds.
40 pub trait Pointer {
41 /// The pointer type constructor.
42 ///
43 /// For `RcBrand`, this is `Rc<T>`. For `ArcBrand`, this is `Arc<T>`.
44 type Of<'a, T: ?Sized + 'a>: Deref<Target = T> + 'a;
45
46 /// Wraps a sized value in the pointer.
47 #[document_signature]
48 ///
49 #[document_type_parameters("The lifetime of the value.", "The type of the value to wrap.")]
50 ///
51 #[document_parameters("The value to wrap.")]
52 ///
53 #[document_returns("The value wrapped in the pointer type.")]
54 #[document_examples]
55 ///
56 /// ```
57 /// use fp_library::{
58 /// brands::*,
59 /// classes::*,
60 /// };
61 ///
62 /// let ptr = <RcBrand as Pointer>::new(42);
63 /// assert_eq!(*ptr, 42);
64 /// ```
65 fn new<'a, T: 'a>(value: T) -> Self::Of<'a, T>
66 where
67 Self::Of<'a, T>: Sized;
68 }
69
70 /// Wraps a sized value in the pointer.
71 #[document_signature]
72 ///
73 #[document_type_parameters(
74 "The pointer brand.",
75 "The lifetime of the value.",
76 "The type of the value to wrap."
77 )]
78 ///
79 #[document_parameters("The value to wrap.")]
80 ///
81 #[document_returns("The value wrapped in the pointer type.")]
82 #[document_examples]
83 ///
84 /// ```
85 /// use fp_library::{
86 /// brands::*,
87 /// functions::*,
88 /// };
89 ///
90 /// let ptr = pointer_new::<RcBrand, _>(42);
91 /// assert_eq!(*ptr, 42);
92 /// ```
93 pub fn new<'a, P: Pointer, T: 'a>(value: T) -> P::Of<'a, T>
94 where
95 P::Of<'a, T>: Sized, {
96 P::new(value)
97 }
98}
99
100pub use inner::*;