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}