Skip to main content

fp_library/classes/
pointer.rs

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