Skip to main content

qubit_function/suppliers/supplier/
box_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 `BoxSupplier` public type.
12
13use super::{
14    BoxSupplierOnce,
15    Predicate,
16    RcSupplier,
17    Supplier,
18    Transformer,
19    impl_box_conversions,
20    impl_box_supplier_methods,
21    impl_supplier_common_methods,
22    impl_supplier_debug_display,
23};
24
25// ======================================================================
26// BoxSupplier - Single Ownership Implementation
27// ======================================================================
28
29/// Box-based single ownership stateless supplier.
30///
31/// Uses `Box<dyn Fn() -> T>` for single ownership scenarios. This
32/// is the most lightweight stateless supplier with zero reference
33/// counting overhead.
34///
35/// # Ownership Model
36///
37/// Methods consume `self` (move semantics) or borrow `&self` for
38/// read-only operations. When you call methods like `map()`, the
39/// original supplier is consumed and you get a new one:
40///
41/// ```rust
42/// use qubit_function::{BoxSupplier, Supplier};
43///
44/// let supplier = BoxSupplier::new(|| 10);
45/// let mapped = supplier.map(|x| x * 2);
46/// // supplier is no longer usable here
47/// ```
48///
49/// # Examples
50///
51/// ## Constant Factory
52///
53/// ```rust
54/// use qubit_function::{BoxSupplier, Supplier};
55///
56/// let factory = BoxSupplier::new(|| 42);
57/// assert_eq!(factory.get(), 42);
58/// assert_eq!(factory.get(), 42);
59/// ```
60///
61/// ## Method Chaining
62///
63/// ```rust
64/// use qubit_function::{BoxSupplier, Supplier};
65///
66/// let pipeline = BoxSupplier::new(|| 10)
67///     .map(|x| x * 2)
68///     .map(|x| x + 5);
69///
70/// assert_eq!(pipeline.get(), 25);
71/// ```
72///
73pub struct BoxSupplier<T> {
74    pub(super) function: Box<dyn Fn() -> T>,
75    pub(super) name: Option<String>,
76}
77
78impl<T> BoxSupplier<T> {
79    // Generates: new(), new_with_name(), name(), set_name(), constant()
80    impl_supplier_common_methods!(BoxSupplier<T>, (Fn() -> T + 'static), |f| Box::new(f));
81
82    // Generates: map(), filter(), zip()
83    impl_box_supplier_methods!(BoxSupplier<T>, Supplier);
84}
85
86// Generates: Debug and Display implementations for BoxSupplier<T>
87impl_supplier_debug_display!(BoxSupplier<T>);
88
89impl<T> Supplier<T> for BoxSupplier<T> {
90    fn get(&self) -> T {
91        (self.function)()
92    }
93
94    // Generates: into_box(), into_rc(), into_fn(), into_once()
95    impl_box_conversions!(
96        BoxSupplier<T>,
97        RcSupplier,
98        Fn() -> T,
99        BoxSupplierOnce
100    );
101}