Skip to main content

qubit_function/functions/mutating_function/
box_mutating_function.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! Defines the `BoxMutatingFunction` public type.
10
11#![allow(unused_imports)]
12
13use super::*;
14
15// =======================================================================
16// 3. BoxMutatingFunction - Single Ownership Implementation
17// =======================================================================
18
19/// BoxMutatingFunction struct
20///
21/// A mutating function implementation based on `Box<dyn Fn(&mut T) -> R>`
22/// for single ownership scenarios. This is the simplest and most efficient
23/// mutating function type when sharing is not required.
24///
25/// # Features
26///
27/// - **Single Ownership**: Not cloneable, ownership moves on use
28/// - **Zero Overhead**: No reference counting or locking
29/// - **Stateless**: Cannot modify captured environment (uses `Fn` not
30///   `FnMut`)
31/// - **Builder Pattern**: Method chaining consumes `self` naturally
32/// - **Factory Methods**: Convenient constructors for common patterns
33///
34/// # Use Cases
35///
36/// Choose `BoxMutatingFunction` when:
37/// - The function is used for stateless operations
38/// - Building pipelines where ownership naturally flows
39/// - No need to share the function across contexts
40/// - Performance is critical and no sharing overhead is acceptable
41///
42/// # Performance
43///
44/// `BoxMutatingFunction` has the best performance among the three function
45/// types:
46/// - No reference counting overhead
47/// - No lock acquisition or runtime borrow checking
48/// - Direct function call through vtable
49/// - Minimal memory footprint (single pointer)
50///
51/// # Examples
52///
53/// ```rust
54/// use qubit_function::{MutatingFunction, BoxMutatingFunction};
55///
56/// let func = BoxMutatingFunction::new(|x: &mut i32| {
57///     *x *= 2;
58///     *x
59/// });
60/// let mut value = 5;
61/// assert_eq!(func.apply(&mut value), 10);
62/// assert_eq!(value, 10);
63/// ```
64///
65/// # Author
66///
67/// Haixing Hu
68pub struct BoxMutatingFunction<T, R> {
69    pub(super) function: Box<dyn Fn(&mut T) -> R>,
70    pub(super) name: Option<String>,
71}
72
73impl<T, R> BoxMutatingFunction<T, R> {
74    // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
75    impl_function_common_methods!(
76        BoxMutatingFunction<T, R>,
77        (Fn(&mut T) -> R + 'static),
78        |f| Box::new(f)
79    );
80
81    // Generates: when(), and_then(), compose()
82    impl_box_function_methods!(
83        BoxMutatingFunction<T, R>,
84        BoxConditionalMutatingFunction,
85        Function  // chains a non-mutating function after this mutating function
86    );
87}
88
89// Generates: Debug and Display implementations for BoxMutatingFunction<T, R>
90impl_function_debug_display!(BoxMutatingFunction<T, R>);
91
92// Generates: identity() method for BoxMutatingFunction<T, T>
93impl_function_identity_method!(BoxMutatingFunction<T, T>, mutating);
94
95// Implement MutatingFunction trait for BoxMutatingFunction<T, R>
96impl<T, R> MutatingFunction<T, R> for BoxMutatingFunction<T, R> {
97    fn apply(&self, t: &mut T) -> R {
98        (self.function)(t)
99    }
100
101    // Generates: into_box(), into_rc(), into_fn(), into_once()
102    impl_box_conversions!(
103        BoxMutatingFunction<T, R>,
104        RcMutatingFunction,
105        Fn(&mut T) -> R,
106        BoxMutatingFunctionOnce
107    );
108}