Skip to main content

qubit_function/suppliers/supplier/
arc_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 `ArcSupplier` public type.
10
11#![allow(unused_imports)]
12
13use super::*;
14
15// ======================================================================
16// ArcSupplier - Thread-safe Shared Ownership Implementation
17// ======================================================================
18
19/// Thread-safe shared ownership stateless supplier.
20///
21/// Uses `Arc<dyn Fn() -> T + Send + Sync>` for thread-safe shared
22/// ownership. **Lock-free** - no `Mutex` needed! Can be cloned and
23/// sent across threads with excellent concurrent performance.
24///
25/// # Ownership Model
26///
27/// Methods borrow `&self` instead of consuming `self`. The
28/// original supplier remains usable after method calls:
29///
30/// ```rust
31/// use qubit_function::{ArcSupplier, Supplier};
32///
33/// let source = ArcSupplier::new(|| 10);
34/// let mapped = source.map(|x| x * 2);
35/// // source is still usable here!
36/// ```
37///
38/// # Lock-Free Performance
39///
40/// Unlike `ArcStatefulSupplier`, this implementation doesn't need `Mutex`.
41/// Multiple threads can call `get()` concurrently without lock
42/// contention, making it ideal for high-concurrency scenarios.
43///
44/// # Examples
45///
46/// ## Thread-safe Factory
47///
48/// ```rust
49/// use qubit_function::{ArcSupplier, Supplier};
50/// use std::thread;
51///
52/// let factory = ArcSupplier::new(|| {
53///     String::from("Hello")
54/// });
55///
56/// let f1 = factory.clone();
57/// let f2 = factory.clone();
58///
59/// let h1 = thread::spawn(move || f1.get());
60/// let h2 = thread::spawn(move || f2.get());
61///
62/// assert_eq!(h1.join().unwrap(), "Hello");
63/// assert_eq!(h2.join().unwrap(), "Hello");
64/// ```
65///
66/// ## Reusable Transformations
67///
68/// ```rust
69/// use qubit_function::{ArcSupplier, Supplier};
70///
71/// let base = ArcSupplier::new(|| 10);
72/// let doubled = base.map(|x| x * 2);
73/// let tripled = base.map(|x| x * 3);
74///
75/// // All remain usable
76/// assert_eq!(base.get(), 10);
77/// assert_eq!(doubled.get(), 20);
78/// assert_eq!(tripled.get(), 30);
79/// ```
80///
81/// # Author
82///
83/// Haixing Hu
84pub struct ArcSupplier<T> {
85    pub(super) function: Arc<dyn Fn() -> T + Send + Sync>,
86    pub(super) name: Option<String>,
87}
88
89impl<T> ArcSupplier<T> {
90    // Generates: new(), new_with_name(), name(), set_name()
91    // Note: constant() is NOT generated here, implemented separately below
92    crate::macros::impl_common_new_methods!(
93        (Fn() -> T + Send + Sync + 'static),
94        |f| Arc::new(f),
95        "supplier"
96    );
97
98    crate::macros::impl_common_name_methods!("supplier");
99
100    // Generates: map(), filter(), zip()
101    impl_shared_supplier_methods!(ArcSupplier<T>, Supplier, (arc));
102}
103
104// Separate impl block for constant() with stricter T: Sync bound
105impl<T> ArcSupplier<T> {
106    /// Creates a supplier that returns a constant value.
107    ///
108    /// Creates a supplier that always returns the same value. Useful for
109    /// default values or placeholder implementations.
110    ///
111    /// **Note:** This method requires `T: Sync` because the constant value
112    /// is captured by a `Fn` closure which needs to be `Sync` for `Arc`.
113    ///
114    /// # Parameters
115    ///
116    /// * `value` - The constant value to return
117    ///
118    /// # Returns
119    ///
120    /// Returns a new supplier instance that returns the constant value.
121    ///
122    /// # Examples
123    ///
124    /// ```rust
125    /// use qubit_function::{ArcSupplier, Supplier};
126    ///
127    /// let supplier = ArcSupplier::constant(42);
128    /// assert_eq!(supplier.get(), 42);
129    /// assert_eq!(supplier.get(), 42); // Can be called multiple times
130    /// ```
131    pub fn constant(value: T) -> Self
132    where
133        T: Clone + Send + Sync + 'static,
134    {
135        Self::new(move || value.clone())
136    }
137}
138
139// Generates: Debug and Display implementations for ArcSupplier<T>
140impl_supplier_debug_display!(ArcSupplier<T>);
141
142// Generates: Clone implementation for ArcSupplier<T>
143impl_supplier_clone!(ArcSupplier<T>);
144
145impl<T> Supplier<T> for ArcSupplier<T> {
146    fn get(&self) -> T {
147        (self.function)()
148    }
149
150    // Use macro to implement conversion methods
151    impl_arc_conversions!(
152        ArcSupplier<T>,
153        BoxSupplier,
154        RcSupplier,
155        BoxSupplierOnce,
156        Fn() -> T
157    );
158}