Skip to main content

qubit_function/functions/
mutating_function.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # MutatingFunction Types
10//!
11//! Provides Java-like `MutatingFunction` interface implementations for
12//! performing operations that accept a mutable reference and return a result.
13//!
14//! It is similar to the `Fn(&mut T) -> R` trait in the standard library.
15//!
16//! This module provides a unified `MutatingFunction` trait and three concrete
17//! implementations based on different ownership models:
18//!
19//! - **`BoxMutatingFunction<T, R>`**: Box-based single ownership
20//!   implementation
21//! - **`ArcMutatingFunction<T, R>`**: Arc-based thread-safe shared ownership
22//!   implementation
23//! - **`RcMutatingFunction<T, R>`**: Rc-based single-threaded shared
24//!   ownership implementation
25//!
26//! # Design Philosophy
27//!
28//! `MutatingFunction` bridges the gap between `Function` and `Mutator`:
29//!
30//! - **Function**: `Fn(&T) -> R` - reads input, returns result
31//! - **Mutator**: `Fn(&mut T)` - modifies input, no return
32//! - **MutatingFunction**: `Fn(&mut T) -> R` - modifies input AND returns
33//!   result
34//!
35//! ## Comparison with Related Types
36//!
37//! | Type | Input | Modifies? | Returns? | Use Cases |
38//! |------|-------|-----------|----------|-----------|
39//! | **Function** | `&T` | ❌ | ✅ | Read-only transform |
40//! | **Mutator** | `&mut T` | ✅ | ❌ | In-place modification |
41//! | **MutatingFunction** | `&mut T` | ✅ | ✅ | Modify + return info |
42//! | **Transformer** | `T` | N/A | ✅ | Consume + transform |
43//!
44//! **Key Insight**: Use `MutatingFunction` when you need to both modify the
45//! input and return information about the modification or the previous state.
46//!
47//! # Comparison Table
48//!
49//! | Feature          | Box | Arc | Rc |
50//! |------------------|-----|-----|----|
51//! | Ownership        | Single | Shared | Shared |
52//! | Cloneable        | ❌ | ✅ | ✅ |
53//! | Thread-Safe      | ❌ | ✅ | ❌ |
54//! | Interior Mut.    | N/A | N/A | N/A |
55//! | `and_then` API   | `self` | `&self` | `&self` |
56//! | Lock Overhead    | None | None | None |
57//!
58//! # Use Cases
59//!
60//! ## Common Scenarios
61//!
62//! - **Atomic operations**: Increment counter and return new value
63//! - **Cache updates**: Update cache and return old value
64//! - **Validation**: Validate and fix data, return validation result
65//! - **Event handlers**: Process event and return whether to continue
66//! - **State machines**: Transition state and return transition info
67//!
68//! # Examples
69//!
70//! ## Basic Usage
71//!
72//! ```rust
73//! use qubit_function::{BoxMutatingFunction, MutatingFunction};
74//!
75//! // Increment counter and return new value
76//! let incrementer = BoxMutatingFunction::new(|x: &mut i32| {
77//!     *x += 1;
78//!     *x
79//! });
80//!
81//! let mut value = 5;
82//! let result = incrementer.apply(&mut value);
83//! assert_eq!(value, 6);
84//! assert_eq!(result, 6);
85//! ```
86//!
87//! ## Method Chaining
88//!
89//! ```rust
90//! use qubit_function::{BoxMutatingFunction, MutatingFunction};
91//!
92//! let chained = BoxMutatingFunction::new(|x: &mut i32| {
93//!     *x *= 2;
94//!     *x
95//! })
96//! .and_then(|x: &i32| x + 10);
97//!
98//! let mut value = 5;
99//! let result = chained.apply(&mut value);
100//! assert_eq!(value, 10); // (5 * 2), value is still mutated by the first function
101//! assert_eq!(result, 20);
102//! ```
103//!
104//! ## Cache Update Pattern
105//!
106//! ```rust
107//! use qubit_function::{BoxMutatingFunction, MutatingFunction};
108//! use std::collections::HashMap;
109//!
110//! let updater = BoxMutatingFunction::new(
111//!     |cache: &mut HashMap<String, i32>| {
112//!         cache.insert("key".to_string(), 42)
113//!     }
114//! );
115//!
116//! let mut cache = HashMap::new();
117//! cache.insert("key".to_string(), 10);
118//! let old_value = updater.apply(&mut cache);
119//! assert_eq!(old_value, Some(10));
120//! assert_eq!(cache.get("key"), Some(&42));
121//! ```
122//!
123//! # Author
124//!
125//! Haixing Hu
126use std::rc::Rc;
127use std::sync::Arc;
128
129use crate::functions::{
130    function::Function,
131    macros::{
132        impl_box_conditional_function,
133        impl_box_function_methods,
134        impl_conditional_function_clone,
135        impl_conditional_function_debug_display,
136        impl_fn_ops_trait,
137        impl_function_clone,
138        impl_function_common_methods,
139        impl_function_debug_display,
140        impl_function_identity_method,
141        impl_shared_conditional_function,
142        impl_shared_function_methods,
143    },
144    mutating_function_once::BoxMutatingFunctionOnce,
145};
146use crate::macros::{
147    impl_arc_conversions,
148    impl_box_conversions,
149    impl_closure_trait,
150    impl_rc_conversions,
151};
152use crate::predicates::predicate::{
153    ArcPredicate,
154    BoxPredicate,
155    Predicate,
156    RcPredicate,
157};
158
159mod box_mutating_function;
160pub use box_mutating_function::BoxMutatingFunction;
161mod rc_mutating_function;
162pub use rc_mutating_function::RcMutatingFunction;
163mod arc_mutating_function;
164pub use arc_mutating_function::ArcMutatingFunction;
165mod box_conditional_mutating_function;
166pub use box_conditional_mutating_function::BoxConditionalMutatingFunction;
167mod rc_conditional_mutating_function;
168pub use rc_conditional_mutating_function::RcConditionalMutatingFunction;
169mod arc_conditional_mutating_function;
170pub use arc_conditional_mutating_function::ArcConditionalMutatingFunction;
171mod fn_mutating_function_ops;
172pub use fn_mutating_function_ops::FnMutatingFunctionOps;
173
174// =======================================================================
175// 1. MutatingFunction Trait - Unified Interface
176// =======================================================================
177
178/// MutatingFunction trait - Unified mutating function interface
179///
180/// It is similar to the `Fn(&mut T) -> R` trait in the standard library.
181///
182/// Defines the core behavior of all mutating function types. Performs
183/// operations that accept a mutable reference, potentially modify it, and
184/// return a result.
185///
186/// This trait is automatically implemented by:
187/// - All closures implementing `Fn(&mut T) -> R`
188/// - `BoxMutatingFunction<T, R>`, `ArcMutatingFunction<T, R>`, and
189///   `RcMutatingFunction<T, R>`
190///
191/// # Design Rationale
192///
193/// The trait provides a unified abstraction over different ownership models
194/// for operations that both modify input and return results. This is useful
195/// for scenarios where you need to:
196/// - Update state and return information about the update
197/// - Perform atomic-like operations (modify and return)
198/// - Implement event handlers that modify state and signal continuation
199///
200/// # Features
201///
202/// - **Unified Interface**: All mutating function types share the same
203///   `apply` method signature
204/// - **Automatic Implementation**: Closures automatically implement this
205///   trait
206/// - **Type Conversions**: Easy conversion between ownership models
207/// - **Generic Programming**: Write functions that work with any mutating
208///   function type
209///
210/// # Examples
211///
212/// ## Generic Function
213///
214/// ```rust
215/// use qubit_function::{MutatingFunction, BoxMutatingFunction};
216///
217/// fn apply_and_log<F: MutatingFunction<i32, i32>>(
218///     func: &F,
219///     value: i32
220/// ) -> i32 {
221///     let mut val = value;
222///     let result = func.apply(&mut val);
223///     println!("Modified: {} -> {}, returned: {}", value, val, result);
224///     result
225/// }
226///
227/// let incrementer = BoxMutatingFunction::new(|x: &mut i32| {
228///     *x += 1;
229///     *x
230/// });
231/// assert_eq!(apply_and_log(&incrementer, 5), 6);
232/// ```
233///
234/// ## Type Conversion
235///
236/// ```rust
237/// use qubit_function::MutatingFunction;
238///
239/// let closure = |x: &mut i32| {
240///     *x *= 2;
241///     *x
242/// };
243///
244/// // Convert to different ownership models
245/// let box_func = closure.into_box();
246/// // let rc_func = closure.into_rc();  // closure moved
247/// // let arc_func = closure.into_arc(); // closure moved
248/// ```
249///
250/// # Author
251///
252/// Haixing Hu
253pub trait MutatingFunction<T, R> {
254    /// Applies the function to the mutable reference and returns a result
255    ///
256    /// Executes an operation on the given mutable reference, potentially
257    /// modifying it, and returns a result value.
258    ///
259    /// # Parameters
260    ///
261    /// * `t` - A mutable reference to the input value
262    ///
263    /// # Returns
264    ///
265    /// The computed result value
266    ///
267    /// # Examples
268    ///
269    /// ```rust
270    /// use qubit_function::{MutatingFunction, BoxMutatingFunction};
271    ///
272    /// let func = BoxMutatingFunction::new(|x: &mut i32| {
273    ///     let old = *x;
274    ///     *x += 1;
275    ///     old
276    /// });
277    ///
278    /// let mut value = 5;
279    /// let old_value = func.apply(&mut value);
280    /// assert_eq!(old_value, 5);
281    /// assert_eq!(value, 6);
282    /// ```
283    fn apply(&self, t: &mut T) -> R;
284
285    /// Convert this mutating function into a `BoxMutatingFunction<T, R>`.
286    ///
287    /// This consuming conversion takes ownership of `self` and returns a
288    /// boxed implementation that forwards calls to the original function.
289    /// Types that can provide a more efficient conversion may override the
290    /// default implementation.
291    ///
292    /// # Consumption
293    ///
294    /// This method consumes the function: the original value will no longer
295    /// be available after the call. For cloneable functions call `.clone()`
296    /// before converting if you need to retain the original instance.
297    ///
298    /// # Returns
299    ///
300    /// A `BoxMutatingFunction<T, R>` that forwards to the original function.
301    ///
302    /// # Examples
303    ///
304    /// ```rust
305    /// use qubit_function::MutatingFunction;
306    ///
307    /// let closure = |x: &mut i32| {
308    ///     *x *= 2;
309    ///     *x
310    /// };
311    /// let mut boxed = closure.into_box();
312    /// let mut value = 5;
313    /// assert_eq!(boxed.apply(&mut value), 10);
314    /// ```
315    fn into_box(self) -> BoxMutatingFunction<T, R>
316    where
317        Self: Sized + 'static,
318    {
319        BoxMutatingFunction::new(move |t| self.apply(t))
320    }
321
322    /// Convert this mutating function into an `RcMutatingFunction<T, R>`.
323    ///
324    /// This consuming conversion takes ownership of `self` and returns an
325    /// `Rc`-backed function that forwards calls to the original. Override to
326    /// provide a more direct or efficient conversion when available.
327    ///
328    /// # Consumption
329    ///
330    /// This method consumes the function. If you need to keep the original
331    /// instance, clone it prior to calling this method.
332    ///
333    /// # Returns
334    ///
335    /// An `RcMutatingFunction<T, R>` forwarding to the original function.
336    ///
337    /// # Examples
338    ///
339    /// ```rust
340    /// use qubit_function::MutatingFunction;
341    ///
342    /// let closure = |x: &mut i32| {
343    ///     *x *= 2;
344    ///     *x
345    /// };
346    /// let mut rc = closure.into_rc();
347    /// let mut value = 5;
348    /// assert_eq!(rc.apply(&mut value), 10);
349    /// ```
350    fn into_rc(self) -> RcMutatingFunction<T, R>
351    where
352        Self: Sized + 'static,
353    {
354        RcMutatingFunction::new(move |t| self.apply(t))
355    }
356
357    /// Convert this mutating function into an `ArcMutatingFunction<T, R>`.
358    ///
359    /// This consuming conversion takes ownership of `self` and returns an
360    /// `Arc`-wrapped, thread-safe function. Types may override the default
361    /// implementation to provide a more efficient conversion.
362    ///
363    /// # Consumption
364    ///
365    /// This method consumes the function. Clone the instance first if you
366    /// need to retain the original for further use.
367    ///
368    /// # Returns
369    ///
370    /// An `ArcMutatingFunction<T, R>` that forwards to the original
371    /// function.
372    ///
373    /// # Examples
374    ///
375    /// ```rust
376    /// use qubit_function::MutatingFunction;
377    ///
378    /// let closure = |x: &mut i32| {
379    ///     *x *= 2;
380    ///     *x
381    /// };
382    /// let mut arc = closure.into_arc();
383    /// let mut value = 5;
384    /// assert_eq!(arc.apply(&mut value), 10);
385    /// ```
386    fn into_arc(self) -> ArcMutatingFunction<T, R>
387    where
388        Self: Sized + Send + Sync + 'static,
389    {
390        ArcMutatingFunction::new(move |t| self.apply(t))
391    }
392
393    /// Consume the function and return an `Fn(&mut T) -> R` closure.
394    ///
395    /// The returned closure forwards calls to the original function and is
396    /// suitable for use with iterator adapters or other contexts expecting
397    /// closures.
398    ///
399    /// # Consumption
400    ///
401    /// This method consumes the function. The original instance will not be
402    /// available after calling this method.
403    ///
404    /// # Returns
405    ///
406    /// A closure implementing `Fn(&mut T) -> R` which forwards to the
407    /// original function.
408    ///
409    /// # Examples
410    ///
411    /// ```rust
412    /// use qubit_function::{MutatingFunction, BoxMutatingFunction};
413    ///
414    /// let func = BoxMutatingFunction::new(|x: &mut i32| {
415    ///     *x *= 2;
416    ///     *x
417    /// });
418    /// let closure = func.into_fn();
419    /// let mut value = 5;
420    /// assert_eq!(closure(&mut value), 10);
421    /// ```
422    fn into_fn(self) -> impl Fn(&mut T) -> R
423    where
424        Self: Sized + 'static,
425    {
426        move |t| self.apply(t)
427    }
428
429    /// Convert to MutatingFunctionOnce
430    ///
431    /// **⚠️ Consumes `self`**: The original function will be unavailable
432    /// after calling this method.
433    ///
434    /// Converts a reusable mutating function to a one-time function that
435    /// consumes itself on use. This enables passing `MutatingFunction` to
436    /// functions that require `MutatingFunctionOnce`.
437    ///
438    /// # Returns
439    ///
440    /// Returns a `BoxMutatingFunctionOnce<T, R>`
441    ///
442    /// # Examples
443    ///
444    /// ```rust
445    /// use qubit_function::{MutatingFunctionOnce, MutatingFunction,
446    ///                       ArcMutatingFunction, BoxMutatingFunction};
447    ///
448    /// fn takes_once<F: MutatingFunctionOnce<i32, i32>>(func: F, value: &mut i32) {
449    ///     let result = func.apply(value);
450    ///     println!("Result: {}", result);
451    /// }
452    ///
453    /// let func = BoxMutatingFunction::new(|x: &mut i32| {
454    ///     *x *= 2;
455    ///     *x
456    /// });
457    /// let mut value = 5;
458    /// takes_once(func.into_once(), &mut value);
459    /// ```
460    fn into_once(self) -> BoxMutatingFunctionOnce<T, R>
461    where
462        Self: Sized + 'static,
463    {
464        BoxMutatingFunctionOnce::new(move |t| self.apply(t))
465    }
466
467    /// Create a non-consuming `BoxMutatingFunction<T, R>` that forwards to
468    /// `self`.
469    ///
470    /// The default implementation clones `self` (requires `Clone`) and
471    /// returns a boxed function that calls the cloned instance. Override this
472    /// method if a more efficient conversion exists.
473    ///
474    /// # Returns
475    ///
476    /// A `BoxMutatingFunction<T, R>` that forwards to a clone of `self`.
477    fn to_box(&self) -> BoxMutatingFunction<T, R>
478    where
479        Self: Sized + Clone + 'static,
480    {
481        self.clone().into_box()
482    }
483
484    /// Create a non-consuming `RcMutatingFunction<T, R>` that forwards to
485    /// `self`.
486    ///
487    /// The default implementation clones `self` (requires `Clone`) and
488    /// returns an `Rc`-backed function that forwards calls to the clone.
489    /// Override to provide a more direct or efficient conversion if needed.
490    ///
491    /// # Returns
492    ///
493    /// An `RcMutatingFunction<T, R>` that forwards to a clone of `self`.
494    fn to_rc(&self) -> RcMutatingFunction<T, R>
495    where
496        Self: Sized + Clone + 'static,
497    {
498        self.clone().into_rc()
499    }
500
501    /// Create a non-consuming `ArcMutatingFunction<T, R>` that forwards to
502    /// `self`.
503    ///
504    /// The default implementation clones `self` (requires
505    /// `Clone + Send + Sync`) and returns an `Arc`-wrapped function that
506    /// forwards calls to the clone. Override when a more efficient conversion
507    /// is available.
508    ///
509    /// # Returns
510    ///
511    /// An `ArcMutatingFunction<T, R>` that forwards to a clone of `self`.
512    fn to_arc(&self) -> ArcMutatingFunction<T, R>
513    where
514        Self: Sized + Clone + Send + Sync + 'static,
515    {
516        self.clone().into_arc()
517    }
518
519    /// Create a boxed `Fn(&mut T) -> R` closure that forwards to `self`.
520    ///
521    /// The default implementation clones `self` (requires `Clone`) and
522    /// returns a boxed closure that invokes the cloned instance. Override to
523    /// provide a more efficient conversion when possible.
524    ///
525    /// # Returns
526    ///
527    /// A closure implementing `Fn(&mut T) -> R` which forwards to the
528    /// original function.
529    fn to_fn(&self) -> impl Fn(&mut T) -> R
530    where
531        Self: Sized + Clone + 'static,
532    {
533        self.clone().into_fn()
534    }
535
536    /// Convert to MutatingFunctionOnce without consuming self
537    ///
538    /// **⚠️ Requires Clone**: This method requires `Self` to implement `Clone`.
539    /// Clones the current function and converts the clone to a one-time function.
540    ///
541    /// # Returns
542    ///
543    /// Returns a `BoxMutatingFunctionOnce<T, R>`
544    ///
545    /// # Examples
546    ///
547    /// ```rust
548    /// use qubit_function::{MutatingFunctionOnce, MutatingFunction,
549    ///                       ArcMutatingFunction};
550    ///
551    /// fn takes_once<F: MutatingFunctionOnce<i32, i32>>(func: F, value: &mut i32) {
552    ///     let result = func.apply(value);
553    ///     println!("Result: {}", result);
554    /// }
555    ///
556    /// let func = ArcMutatingFunction::new(|x: &mut i32| {
557    ///     *x *= 2;
558    ///     *x
559    /// });
560    /// let mut value = 5;
561    /// takes_once(func.to_once(), &mut value);
562    /// ```
563    fn to_once(&self) -> BoxMutatingFunctionOnce<T, R>
564    where
565        Self: Clone + 'static,
566    {
567        self.clone().into_once()
568    }
569}