Skip to main content

qubit_function/mutators/
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//! # Mutator Types (Stateless)
11//!
12//! Provides Java-like `Mutator` interface implementations for performing
13//! **stateless** operations that accept a single mutable input parameter and
14//! return no result.
15//!
16//! This module provides a unified `Mutator` trait and three concrete
17//! implementations based on different ownership models:
18//!
19//! - **`BoxMutator<T>`**: Box-based single ownership implementation for
20//!   one-time use scenarios and builder patterns
21//! - **`ArcMutator<T>`**: Arc-based thread-safe shared ownership
22//!   implementation for multi-threaded scenarios
23//! - **`RcMutator<T>`**: Rc-based single-threaded shared
24//!   ownership implementation with no lock overhead
25//!
26//! It is similar to the `Fn(&mut T)` trait in the standard library.
27//!
28//! # Design Philosophy
29//!
30//! `Mutator` is designed for **stateless** operations using `Fn(&mut T)`.
31//! Unlike `StatefulMutator` which uses `FnMut(&mut T)` and can maintain internal
32//! state, `Mutator` operations are pure transformations without side effects on
33//! the mutator itself.
34//!
35//! ## Mutator vs StatefulMutator vs Consumer
36//!
37//! | Type | Input | Modifies Input? | Modifies Self? | Use Cases |
38//! |------|-------|----------------|----------------|-----------|
39//! | **Consumer** | `&T` | ❌ | ✅ | Observe, log, count, notify |
40//! | **Mutator** | `&mut T` | ✅ | ❌ | Pure transform, validate, normalize |
41//! | **StatefulMutator** | `&mut T` | ✅ | ✅ | Stateful transform, accumulate |
42//!
43//! **Key Insight**: Use `Mutator` for stateless transformations,
44//! `StatefulMutator` for stateful operations, and `Consumer` for observation.
45//!
46//! # Comparison Table
47//!
48//! | Feature          | BoxMutator | ArcMutator | RcMutator |
49//! |------------------|------------|------------|-----------|
50//! | Ownership        | Single     | Shared     | Shared    |
51//! | Cloneable        | ❌         | ✅         | ✅        |
52//! | Thread-Safe      | ❌         | ✅         | ❌        |
53//! | Interior Mut.    | N/A        | N/A        | N/A       |
54//! | `and_then` API   | `self`     | `&self`    | `&self`   |
55//! | Lock Overhead    | None       | None       | None      |
56//!
57//! # Use Cases
58//!
59//! ## BoxMutator
60//!
61//! - One-time operations that don't require sharing
62//! - Builder patterns where ownership naturally flows
63//! - Simple scenarios with no reuse requirements
64//!
65//! ## ArcMutator
66//!
67//! - Multi-threaded shared operations
68//! - Concurrent task processing (e.g., thread pools)
69//! - Situations requiring the same mutator across threads
70//!
71//! ## RcMutator
72//!
73//! - Single-threaded operations with multiple uses
74//! - Event handling in single-threaded UI frameworks
75//! - Performance-critical single-threaded scenarios
76//!
77//! # Examples
78//!
79//! ## Basic Usage
80//!
81//! ```rust
82//! use qubit_function::{BoxMutator, ArcMutator, RcMutator, Mutator};
83//!
84//! // BoxMutator: Single ownership, consumes self
85//! let mut mutator = BoxMutator::new(|x: &mut i32| *x *= 2);
86//! let mut value = 5;
87//! mutator.apply(&mut value);
88//! assert_eq!(value, 10);
89//!
90//! // ArcMutator: Shared ownership, cloneable, thread-safe
91//! let shared = ArcMutator::new(|x: &mut i32| *x *= 2);
92//! let clone = shared.clone();
93//! let mut value = 5;
94//! let mut m = shared;
95//! m.apply(&mut value);
96//! assert_eq!(value, 10);
97//!
98//! // RcMutator: Shared ownership, cloneable, single-threaded
99//! let rc = RcMutator::new(|x: &mut i32| *x *= 2);
100//! let clone = rc.clone();
101//! let mut value = 5;
102//! let mut m = rc;
103//! m.apply(&mut value);
104//! assert_eq!(value, 10);
105//! ```
106//!
107//! ## Method Chaining
108//!
109//! ```rust
110//! use qubit_function::{Mutator, BoxMutator, ArcMutator};
111//!
112//! // BoxMutator: Consumes self
113//! let mut chained = BoxMutator::new(|x: &mut i32| *x *= 2)
114//!     .and_then(|x: &mut i32| *x += 10);
115//! let mut value = 5;
116//! chained.apply(&mut value);
117//! assert_eq!(value, 20); // (5 * 2) + 10
118//!
119//! // ArcMutator: Borrows &self, original still usable
120//! let first = ArcMutator::new(|x: &mut i32| *x *= 2);
121//! let second = ArcMutator::new(|x: &mut i32| *x += 10);
122//! let combined = first.clone().and_then(second.clone());
123//! let mut value = 5;
124//! combined.apply(&mut value);
125//! assert_eq!(value, 20); // (5 * 2) + 10
126//! // first and second are still usable here
127//! ```
128//!
129//! ## Working with Closures
130//!
131//! All closures automatically implement the `Mutator` trait:
132//!
133//! ```rust
134//! use qubit_function::{Mutator, FnMutatorOps};
135//!
136//! // Closures can use .apply() directly
137//! let mut closure = |x: &mut i32| *x *= 2;
138//! let mut value = 5;
139//! closure.apply(&mut value);
140//! assert_eq!(value, 10);
141//!
142//! // Closures can be chained, returning BoxMutator
143//! let mut chained = (|x: &mut i32| *x *= 2)
144//!     .and_then(|x: &mut i32| *x += 10);
145//! let mut value = 5;
146//! chained.apply(&mut value);
147//! assert_eq!(value, 20);
148//! ```
149//!
150//! ## Type Conversions
151//!
152//! ```rust
153//! use qubit_function::Mutator;
154//!
155//! // Convert closure to concrete type
156//! let closure = |x: &mut i32| *x *= 2;
157//! let mut box_mutator = closure.into_box();
158//!
159//! let closure = |x: &mut i32| *x *= 2;
160//! let mut rc_mutator = closure.into_rc();
161//!
162//! let closure = |x: &mut i32| *x *= 2;
163//! let mut arc_mutator = closure.into_arc();
164//! ```
165//!
166//! ## Conditional Execution
167//!
168//! All mutator types support conditional execution through the `when` method,
169//! which returns a `ConditionalMutator`. You can optionally add an `or_else`
170//! branch to create if-then-else logic:
171//!
172//! ```rust
173//! use qubit_function::{Mutator, BoxMutator};
174//!
175//! // Simple conditional (if-then)
176//! let mut conditional = BoxMutator::new(|x: &mut i32| *x *= 2)
177//!     .when(|x: &i32| *x > 0);
178//!
179//! let mut positive = 5;
180//! conditional.apply(&mut positive);
181//! assert_eq!(positive, 10); // Executed
182//!
183//! let mut negative = -5;
184//! conditional.apply(&mut negative);
185//! assert_eq!(negative, -5); // Not executed
186//!
187//! // Conditional with else branch (if-then-else)
188//! let mut branched = BoxMutator::new(|x: &mut i32| *x *= 2)
189//!     .when(|x: &i32| *x > 0)
190//!     .or_else(|x: &mut i32| *x -= 1);
191//!
192//! let mut positive = 5;
193//! branched.apply(&mut positive);
194//! assert_eq!(positive, 10); // when branch
195//!
196//! let mut negative = -5;
197//! branched.apply(&mut negative);
198//! assert_eq!(negative, -6); // or_else branch
199//! ```
200//!
201use std::rc::Rc;
202use std::sync::Arc;
203
204use crate::macros::{
205    impl_arc_conversions,
206    impl_box_conversions,
207    impl_closure_trait,
208    impl_rc_conversions,
209};
210use crate::mutators::{
211    macros::{
212        impl_box_conditional_mutator,
213        impl_box_mutator_methods,
214        impl_conditional_mutator_clone,
215        impl_conditional_mutator_conversions,
216        impl_conditional_mutator_debug_display,
217        impl_mutator_clone,
218        impl_mutator_common_methods,
219        impl_mutator_debug_display,
220        impl_shared_conditional_mutator,
221        impl_shared_mutator_methods,
222    },
223    mutator_once::BoxMutatorOnce,
224};
225use crate::predicates::predicate::{
226    ArcPredicate,
227    BoxPredicate,
228    Predicate,
229    RcPredicate,
230};
231
232// ============================================================================
233// 1. Type Aliases
234// ============================================================================
235
236/// Type alias for Arc-wrapped stateless mutator function
237type ArcMutatorFn<T> = Arc<dyn Fn(&mut T) + Send + Sync>;
238
239/// Type alias for Rc-wrapped stateless mutator function
240type RcMutatorFn<T> = Rc<dyn Fn(&mut T)>;
241
242mod box_mutator;
243pub use box_mutator::BoxMutator;
244mod rc_mutator;
245pub use rc_mutator::RcMutator;
246mod arc_mutator;
247pub use arc_mutator::ArcMutator;
248mod fn_mutator_ops;
249pub use fn_mutator_ops::FnMutatorOps;
250mod box_conditional_mutator;
251pub use box_conditional_mutator::BoxConditionalMutator;
252mod rc_conditional_mutator;
253pub use rc_conditional_mutator::RcConditionalMutator;
254mod arc_conditional_mutator;
255pub use arc_conditional_mutator::ArcConditionalMutator;
256
257// ============================================================================
258// 2. Mutator Trait - Unified Mutator Interface
259// ============================================================================
260
261/// Mutator trait - Unified stateless mutator interface
262///
263/// Defines the core behavior of all stateless mutator types. Performs operations
264/// that accept a mutable reference and modify the input value without maintaining
265/// internal state.
266///
267/// This trait is automatically implemented by:
268/// - All closures implementing `Fn(&mut T)` (stateless)
269/// - `BoxMutator<T>`, `ArcMutator<T>`, and `RcMutator<T>`
270///
271/// # Design Rationale
272///
273/// The trait provides a unified abstraction over different ownership models for
274/// **stateless** operations. Unlike `StatefulMutator` which uses `FnMut` and can
275/// modify its internal state, `Mutator` uses `Fn` for pure transformations.
276///
277/// # Features
278///
279/// - **Stateless Operations**: No internal state modification (`&self` not `&mut self`)
280/// - **Unified Interface**: All mutator types share the same `mutate` method signature
281/// - **Automatic Implementation**: Closures automatically implement this trait
282/// - **Type Conversions**: Easy conversion between ownership models
283/// - **Generic Programming**: Write functions that work with any mutator type
284///
285/// # Examples
286///
287/// ## Generic Mutator Function
288///
289/// ```rust
290/// use qubit_function::{Mutator, BoxMutator, ArcMutator};
291///
292/// fn apply_mutator<M: Mutator<i32>>(
293///     mutator: &mut M,
294///     value: i32
295/// ) -> i32 {
296///     let mut val = value;
297///     mutator.apply(&mut val);
298///     val
299/// }
300///
301/// // Works with any mutator type
302/// let mut box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
303/// assert_eq!(apply_mutator(&mut box_mut, 5), 10);
304///
305/// let mut arc_mut = ArcMutator::new(|x: &mut i32| *x *= 2);
306/// assert_eq!(apply_mutator(&mut arc_mut, 5), 10);
307///
308/// let mut closure = |x: &mut i32| *x *= 2;
309/// assert_eq!(apply_mutator(&mut closure, 5), 10);
310/// ```
311///
312/// ## Type Conversion
313///
314/// ```rust
315/// use qubit_function::Mutator;
316///
317/// let closure = |x: &mut i32| *x *= 2;
318///
319/// // Convert to different ownership models
320/// let box_mutator = closure.into_box();
321/// // let rc_mutator = closure.into_rc();  // closure moved
322/// // let arc_mutator = closure.into_arc(); // closure moved
323/// ```
324///
325pub trait Mutator<T> {
326    /// Performs the stateless mutation operation
327    ///
328    /// Executes an operation on the given mutable reference without modifying
329    /// the mutator's internal state. This is a pure transformation operation.
330    ///
331    /// # Parameters
332    ///
333    /// * `value` - A mutable reference to the value to be mutated
334    ///
335    /// # Examples
336    ///
337    /// ```rust
338    /// use qubit_function::{Mutator, BoxMutator};
339    ///
340    /// let mutator = BoxMutator::new(|x: &mut i32| *x *= 2);
341    /// let mut value = 5;
342    /// mutator.apply(&mut value);
343    /// assert_eq!(value, 10);
344    /// ```
345    fn apply(&self, value: &mut T);
346
347    /// Convert this mutator into a `BoxMutator<T>`.
348    ///
349    /// This consuming conversion takes ownership of `self` and returns a
350    /// boxed implementation that forwards calls to the original mutator.
351    /// Types that can provide a more efficient conversion may override the
352    /// default implementation.
353    ///
354    /// # Consumption
355    ///
356    /// This method consumes the mutator: the original value will no longer
357    /// be available after the call. For cloneable mutators call `.clone()`
358    /// before converting if you need to retain the original instance.
359    ///
360    /// # Returns
361    ///
362    /// A `BoxMutator<T>` that forwards to the original mutator.
363    ///
364    /// # Examples
365    ///
366    /// ```rust
367    /// use qubit_function::Mutator;
368    ///
369    /// let closure = |x: &mut i32| *x *= 2;
370    /// let mut boxed = closure.into_box();
371    /// let mut value = 5;
372    /// boxed.apply(&mut value);
373    /// assert_eq!(value, 10);
374    /// ```
375    fn into_box(self) -> BoxMutator<T>
376    where
377        Self: Sized + 'static,
378    {
379        BoxMutator::new(move |t| self.apply(t))
380    }
381
382    /// Convert this mutator into an `RcMutator<T>`.
383    ///
384    /// This consuming conversion takes ownership of `self` and returns an
385    /// `Rc`-backed mutator that forwards calls to the original. Override to
386    /// provide a more direct or efficient conversion when available.
387    ///
388    /// # Consumption
389    ///
390    /// This method consumes the mutator. If you need to keep the original
391    /// instance, clone it prior to calling this method.
392    ///
393    /// # Returns
394    ///
395    /// An `RcMutator<T>` forwarding to the original mutator.
396    ///
397    /// # Examples
398    ///
399    /// ```rust
400    /// use qubit_function::Mutator;
401    ///
402    /// let closure = |x: &mut i32| *x *= 2;
403    /// let mut rc = closure.into_rc();
404    /// let mut value = 5;
405    /// rc.apply(&mut value);
406    /// assert_eq!(value, 10);
407    /// ```
408    fn into_rc(self) -> RcMutator<T>
409    where
410        Self: Sized + 'static,
411    {
412        RcMutator::new(move |t| self.apply(t))
413    }
414
415    /// Convert this mutator into an `ArcMutator<T>`.
416    ///
417    /// This consuming conversion takes ownership of `self` and returns an
418    /// `Arc`-wrapped, thread-safe mutator. Types may override the default
419    /// implementation to provide a more efficient conversion.
420    ///
421    /// # Consumption
422    ///
423    /// This method consumes the mutator. Clone the instance first if you
424    /// need to retain the original for further use.
425    ///
426    /// # Returns
427    ///
428    /// An `ArcMutator<T>` that forwards to the original mutator.
429    ///
430    /// # Examples
431    ///
432    /// ```rust
433    /// use qubit_function::Mutator;
434    ///
435    /// let closure = |x: &mut i32| *x *= 2;
436    /// let mut arc = closure.into_arc();
437    /// let mut value = 5;
438    /// arc.apply(&mut value);
439    /// assert_eq!(value, 10);
440    /// ```
441    fn into_arc(self) -> ArcMutator<T>
442    where
443        Self: Sized + Send + Sync + 'static,
444    {
445        ArcMutator::new(move |t| self.apply(t))
446    }
447
448    /// Consume the mutator and return an `Fn(&mut T)` closure.
449    ///
450    /// The returned closure forwards calls to the original mutator and is
451    /// suitable for use with iterator adapters such as `for_each`.
452    ///
453    /// # Consumption
454    ///
455    /// This method consumes the mutator. The original instance will not be
456    /// available after calling this method.
457    ///
458    /// # Returns
459    ///
460    /// A closure implementing `Fn(&mut T)` which forwards to the
461    /// original mutator.
462    ///
463    /// # Examples
464    ///
465    /// ```rust
466    /// use qubit_function::{Mutator, BoxMutator};
467    ///
468    /// let mutator = BoxMutator::new(|x: &mut i32| *x *= 2);
469    /// let mut values = vec![1, 2, 3, 4, 5];
470    /// values.iter_mut().for_each(mutator.into_fn());
471    /// assert_eq!(values, vec![2, 4, 6, 8, 10]);
472    /// ```
473    fn into_fn(self) -> impl Fn(&mut T)
474    where
475        Self: Sized + 'static,
476    {
477        move |t| self.apply(t)
478    }
479
480    /// Convert this mutator into a `BoxMutatorOnce<T>` (consuming).
481    ///
482    /// This consuming conversion takes ownership of `self` and returns a
483    /// boxed one-time mutator that forwards calls to the original mutator.
484    /// The returned mutator can only be used once.
485    ///
486    /// # Consumption
487    ///
488    /// This method consumes the mutator: the original value will no longer
489    /// be available after the call. For cloneable mutators call `.clone()`
490    /// before converting if you need to retain the original instance.
491    ///
492    /// # Returns
493    ///
494    /// A `BoxMutatorOnce<T>` that forwards to the original mutator.
495    ///
496    /// # Examples
497    ///
498    /// ```rust
499    /// use qubit_function::{Mutator, MutatorOnce, BoxMutator, BoxMutatorOnce};
500    ///
501    /// let mutator = BoxMutator::new(|x: &mut i32| *x *= 2);
502    /// let once_mutator = mutator.into_once();
503    /// let mut value = 5;
504    /// once_mutator.apply(&mut value);
505    /// assert_eq!(value, 10);
506    /// ```
507    fn into_once(self) -> BoxMutatorOnce<T>
508    where
509        Self: Sized + 'static,
510    {
511        BoxMutatorOnce::new(move |t| self.apply(t))
512    }
513
514    /// Create a non-consuming `BoxMutator<T>` that forwards to `self`.
515    ///
516    /// The default implementation clones `self` (requires `Clone`) and
517    /// returns a boxed mutator that calls the cloned instance. Override this
518    /// method if a more efficient conversion exists.
519    ///
520    /// # Returns
521    ///
522    /// A `BoxMutator<T>` that forwards to a clone of `self`.
523    fn to_box(&self) -> BoxMutator<T>
524    where
525        Self: Sized + Clone + 'static,
526    {
527        self.clone().into_box()
528    }
529
530    /// Create a non-consuming `RcMutator<T>` that forwards to `self`.
531    ///
532    /// The default implementation clones `self` (requires `Clone`) and
533    /// returns an `Rc`-backed mutator that forwards calls to the clone.
534    /// Override to provide a more direct or efficient conversion if needed.
535    ///
536    /// # Returns
537    ///
538    /// An `RcMutator<T>` that forwards to a clone of `self`.
539    fn to_rc(&self) -> RcMutator<T>
540    where
541        Self: Sized + Clone + 'static,
542    {
543        self.clone().into_rc()
544    }
545
546    /// Create a non-consuming `ArcMutator<T>` that forwards to `self`.
547    ///
548    /// The default implementation clones `self` (requires `Clone + Send + Sync`) and
549    /// returns an `Arc`-wrapped mutator that forwards calls to the clone.
550    /// Override when a more efficient conversion is available.
551    ///
552    /// # Returns
553    ///
554    /// An `ArcMutator<T>` that forwards to a clone of `self`.
555    fn to_arc(&self) -> ArcMutator<T>
556    where
557        Self: Sized + Clone + Send + Sync + 'static,
558    {
559        self.clone().into_arc()
560    }
561
562    /// Create a boxed `Fn(&mut T)` closure that forwards to `self`.
563    ///
564    /// The default implementation clones `self` (requires `Clone`) and
565    /// returns a boxed closure that invokes the cloned instance. Override to
566    /// provide a more efficient conversion when possible.
567    ///
568    /// # Returns
569    ///
570    /// A closure implementing `Fn(&mut T)` which forwards to the
571    /// original mutator.
572    fn to_fn(&self) -> impl Fn(&mut T)
573    where
574        Self: Sized + Clone + 'static,
575    {
576        self.clone().into_fn()
577    }
578
579    /// Create a non-consuming `BoxMutatorOnce<T>` that forwards to `self`.
580    ///
581    /// The default implementation clones `self` (requires `Clone`) and
582    /// returns a boxed one-time mutator that calls the cloned instance.
583    /// Override this method if a more efficient conversion exists.
584    ///
585    /// # Returns
586    ///
587    /// A `BoxMutatorOnce<T>` that forwards to a clone of `self`.
588    fn to_once(&self) -> BoxMutatorOnce<T>
589    where
590        Self: Sized + Clone + 'static,
591    {
592        self.clone().into_once()
593    }
594}