Skip to main content

qubit_function/suppliers/supplier_once/
box_supplier_once.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 `BoxSupplierOnce` public type.
12
13use super::{
14    Predicate,
15    SupplierOnce,
16    Transformer,
17    impl_box_once_conversions,
18    impl_box_supplier_methods,
19    impl_closure_once_trait,
20    impl_supplier_common_methods,
21    impl_supplier_debug_display,
22};
23
24// ==========================================================================
25// BoxSupplierOnce - One-time Supplier Implementation
26// ==========================================================================
27
28/// Box-based one-time supplier.
29///
30/// Uses `Box<dyn FnOnce() -> T>` for one-time value generation.
31/// Can only call `get()` once, consuming the supplier.
32///
33/// # Examples
34///
35/// ## Lazy Initialization
36///
37/// ```rust
38/// use qubit_function::{BoxSupplierOnce, SupplierOnce};
39///
40/// let once = BoxSupplierOnce::new(|| {
41///     println!("Expensive initialization");
42///     42
43/// });
44///
45/// let value = once.get(); // Prints: Expensive initialization
46/// assert_eq!(value, 42);
47/// ```
48///
49/// ## Moving Captured Values
50///
51/// ```rust
52/// use qubit_function::{BoxSupplierOnce, SupplierOnce};
53///
54/// let resource = String::from("data");
55/// let once = BoxSupplierOnce::new(move || resource);
56///
57/// let value = once.get();
58/// assert_eq!(value, "data");
59/// ```
60///
61pub struct BoxSupplierOnce<T> {
62    pub(super) function: Box<dyn FnOnce() -> T>,
63    pub(super) name: Option<String>,
64}
65
66impl<T> BoxSupplierOnce<T> {
67    // Generates: new(), new_with_name(), name(), set_name(), constant()
68    impl_supplier_common_methods!(BoxSupplierOnce<T>, (FnOnce() -> T + 'static), |f| Box::new(
69        f
70    ));
71
72    // Generates: map(), filter(), zip()
73    impl_box_supplier_methods!(BoxSupplierOnce<T>, SupplierOnce);
74}
75
76// Generates: implement SupplierOnce for BoxSupplierOnce<T>
77impl<T> SupplierOnce<T> for BoxSupplierOnce<T> {
78    fn get(self) -> T {
79        (self.function)()
80    }
81
82    impl_box_once_conversions!(
83        BoxSupplierOnce<T>,
84        SupplierOnce,
85        FnOnce() -> T
86    );
87}
88
89// Generates: Debug and Display implementations for BoxSupplierOnce<T>
90impl_supplier_debug_display!(BoxSupplierOnce<T>);
91
92// ==========================================================================
93// Implement SupplierOnce for Closures
94// ==========================================================================
95
96// Implement SupplierOnce for all FnOnce() -> T using macro
97impl_closure_once_trait!(
98    SupplierOnce<T>,
99    get,
100    BoxSupplierOnce,
101    FnOnce() -> T
102);