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