Skip to main content

qubit_function/mutators/mutator/
box_mutator.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 `BoxMutator` public type.
12
13use super::{
14    BoxConditionalMutator,
15    BoxMutatorOnce,
16    Mutator,
17    Predicate,
18    RcMutator,
19    impl_box_conversions,
20    impl_box_mutator_methods,
21    impl_mutator_common_methods,
22    impl_mutator_debug_display,
23};
24
25// ============================================================================
26// 3. BoxMutator - Single Ownership Implementation
27// ============================================================================
28
29/// BoxMutator struct
30///
31/// A stateless mutator implementation based on `Box<dyn Fn(&mut T)>` for single
32/// ownership scenarios. This is the simplest and most efficient mutator
33/// type when sharing is not required.
34///
35/// # Features
36///
37/// - **Single Ownership**: Not cloneable, ownership moves on use
38/// - **Zero Overhead**: No reference counting or locking
39/// - **Stateless**: Cannot modify captured environment (uses `Fn` not `FnMut`)
40/// - **Builder Pattern**: Method chaining consumes `self` naturally
41/// - **Factory Methods**: Convenient constructors for common patterns
42///
43/// # Use Cases
44///
45/// Choose `BoxMutator` when:
46/// - The mutator is used for stateless transformations
47/// - Building pipelines where ownership naturally flows
48/// - No need to share the mutator across contexts
49/// - Performance is critical and no sharing overhead is acceptable
50///
51/// # Performance
52///
53/// `BoxMutator` has the best performance among the three mutator types:
54/// - No reference counting overhead
55/// - No lock acquisition or runtime borrow checking
56/// - Direct function call through vtable
57/// - Minimal memory footprint (single pointer)
58///
59/// # Examples
60///
61/// ```rust
62/// use qubit_function::{Mutator, BoxMutator};
63///
64/// let mutator = BoxMutator::new(|x: &mut i32| *x *= 2);
65/// let mut value = 5;
66/// mutator.apply(&mut value);
67/// assert_eq!(value, 10);
68/// ```
69///
70pub struct BoxMutator<T> {
71    pub(super) function: Box<dyn Fn(&mut T)>,
72    pub(super) name: Option<String>,
73}
74
75impl<T> BoxMutator<T> {
76    // Generate common mutator methods (new, new_with_name, name, set_name, noop)
77    impl_mutator_common_methods!(BoxMutator<T>, (Fn(&mut T) + 'static), |f| Box::new(f));
78
79    // Generate box mutator methods (when, and_then, or_else, etc.)
80    impl_box_mutator_methods!(BoxMutator<T>, BoxConditionalMutator, Mutator);
81}
82
83impl<T> Mutator<T> for BoxMutator<T> {
84    fn apply(&self, value: &mut T) {
85        (self.function)(value)
86    }
87
88    // Generates: into_box(), into_rc(), into_fn(), into_once()
89    impl_box_conversions!(BoxMutator<T>, RcMutator, Fn(&mut T), BoxMutatorOnce);
90}
91
92// Generate Debug and Display trait implementations
93impl_mutator_debug_display!(BoxMutator<T>);