Skip to main content

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