Skip to main content

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::*;