Skip to main content

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