Skip to main content

qubit_function/suppliers/supplier/
rc_supplier.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! Defines the `RcSupplier` public type.
10
11#![allow(unused_imports)]
12
13use super::*;
14
15// ======================================================================
16// RcSupplier - Single-threaded Shared Ownership
17// ======================================================================
18
19/// Single-threaded shared ownership stateless supplier.
20///
21/// Uses `Rc<dyn Fn() -> T>` for single-threaded shared ownership.
22/// Can be cloned but not sent across threads.
23///
24/// # Ownership Model
25///
26/// Like `ArcSupplier`, methods borrow `&self` instead of
27/// consuming `self`:
28///
29/// ```rust
30/// use qubit_function::{RcSupplier, Supplier};
31///
32/// let source = RcSupplier::new(|| 10);
33/// let mapped = source.map(|x| x * 2);
34/// // source is still usable here!
35/// ```
36///
37/// # Examples
38///
39/// ## Shared Factory
40///
41/// ```rust
42/// use qubit_function::{RcSupplier, Supplier};
43///
44/// let factory = RcSupplier::new(|| {
45///     String::from("Hello")
46/// });
47///
48/// let f1 = factory.clone();
49/// let f2 = factory.clone();
50/// assert_eq!(f1.get(), "Hello");
51/// assert_eq!(f2.get(), "Hello");
52/// ```
53///
54/// ## Reusable Transformations
55///
56/// ```rust
57/// use qubit_function::{RcSupplier, Supplier};
58///
59/// let base = RcSupplier::new(|| 10);
60/// let doubled = base.map(|x| x * 2);
61/// let tripled = base.map(|x| x * 3);
62///
63/// assert_eq!(base.get(), 10);
64/// assert_eq!(doubled.get(), 20);
65/// assert_eq!(tripled.get(), 30);
66/// ```
67///
68/// # Author
69///
70/// Haixing Hu
71pub struct RcSupplier<T> {
72    pub(super) function: Rc<dyn Fn() -> T>,
73    pub(super) name: Option<String>,
74}
75
76impl<T> RcSupplier<T> {
77    // Generates: new(), new_with_name(), name(), set_name(), constant()
78    impl_supplier_common_methods!(RcSupplier<T>, (Fn() -> T + 'static), |f| Rc::new(f));
79
80    // Generates: map(), filter(), zip()
81    impl_shared_supplier_methods!(
82        RcSupplier<T>,
83        Supplier,
84        ('static)
85    );
86}
87
88// Generates: Debug and Display implementations for RcSupplier<T>
89impl_supplier_debug_display!(RcSupplier<T>);
90
91// Generates: Clone implementation for RcSupplier<T>
92impl_supplier_clone!(RcSupplier<T>);
93
94impl<T> Supplier<T> for RcSupplier<T> {
95    fn get(&self) -> T {
96        (self.function)()
97    }
98
99    // Generate all conversion methods using the unified macro
100    impl_rc_conversions!(
101        RcSupplier<T>,
102        BoxSupplier,
103        BoxSupplierOnce,
104        Fn() -> T
105    );
106}
107
108// ======================================================================
109// Implement Supplier for Closures
110// ======================================================================
111
112// Implement Supplier<T> for any type that implements Fn() -> T
113impl_closure_trait!(
114    Supplier<T>,
115    get,
116    BoxSupplierOnce,
117    Fn() -> T
118);
119
120// ======================================================================
121// Note on Extension Traits for Closures
122// ======================================================================
123//
124// We don't provide `FnSupplierOps` trait for `Fn() -> T` closures
125// because:
126//
127// 1. All `Fn` closures also implement `FnMut`, so they can use `FnSupplierOps`
128//    from the `supplier` module
129// 2. Providing both would cause ambiguity errors due to overlapping trait impls
130// 3. Rust doesn't support negative trait bounds to exclude `FnMut`
131//
132// Users of `Fn` closures should use `FnSupplierOps` from `supplier` module,
133// or explicitly convert to `BoxSupplier` using `.into_box()` first.