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: &mut i32| {
97//! *x += 10;
98//! *x
99//! });
100//!
101//! let mut value = 5;
102//! let result = chained.apply(&mut value);
103//! assert_eq!(value, 20); // (5 * 2) + 10
104//! assert_eq!(result, 20);
105//! ```
106//!
107//! ## Cache Update Pattern
108//!
109//! ```rust
110//! use qubit_function::{BoxMutatingFunction, MutatingFunction};
111//! use std::collections::HashMap;
112//!
113//! let updater = BoxMutatingFunction::new(
114//! |cache: &mut HashMap<String, i32>| {
115//! cache.insert("key".to_string(), 42)
116//! }
117//! );
118//!
119//! let mut cache = HashMap::new();
120//! cache.insert("key".to_string(), 10);
121//! let old_value = updater.apply(&mut cache);
122//! assert_eq!(old_value, Some(10));
123//! assert_eq!(cache.get("key"), Some(&42));
124//! ```
125//!
126//! # Author
127//!
128//! Haixing Hu
129use std::rc::Rc;
130use std::sync::Arc;
131
132use crate::functions::{
133 function::Function,
134 macros::{
135 impl_box_conditional_function,
136 impl_box_function_methods,
137 impl_conditional_function_clone,
138 impl_conditional_function_debug_display,
139 impl_fn_ops_trait,
140 impl_function_clone,
141 impl_function_common_methods,
142 impl_function_debug_display,
143 impl_function_identity_method,
144 impl_shared_conditional_function,
145 impl_shared_function_methods,
146 },
147 mutating_function_once::BoxMutatingFunctionOnce,
148};
149use crate::macros::{
150 impl_arc_conversions,
151 impl_box_conversions,
152 impl_closure_trait,
153 impl_rc_conversions,
154};
155use crate::predicates::predicate::{
156 ArcPredicate,
157 BoxPredicate,
158 Predicate,
159 RcPredicate,
160};
161
162// =======================================================================
163// 1. MutatingFunction Trait - Unified Interface
164// =======================================================================
165
166/// MutatingFunction trait - Unified mutating function interface
167///
168/// It is similar to the `Fn(&mut T) -> R` trait in the standard library.
169///
170/// Defines the core behavior of all mutating function types. Performs
171/// operations that accept a mutable reference, potentially modify it, and
172/// return a result.
173///
174/// This trait is automatically implemented by:
175/// - All closures implementing `Fn(&mut T) -> R`
176/// - `BoxMutatingFunction<T, R>`, `ArcMutatingFunction<T, R>`, and
177/// `RcMutatingFunction<T, R>`
178///
179/// # Design Rationale
180///
181/// The trait provides a unified abstraction over different ownership models
182/// for operations that both modify input and return results. This is useful
183/// for scenarios where you need to:
184/// - Update state and return information about the update
185/// - Perform atomic-like operations (modify and return)
186/// - Implement event handlers that modify state and signal continuation
187///
188/// # Features
189///
190/// - **Unified Interface**: All mutating function types share the same
191/// `apply` method signature
192/// - **Automatic Implementation**: Closures automatically implement this
193/// trait
194/// - **Type Conversions**: Easy conversion between ownership models
195/// - **Generic Programming**: Write functions that work with any mutating
196/// function type
197///
198/// # Examples
199///
200/// ## Generic Function
201///
202/// ```rust
203/// use qubit_function::{MutatingFunction, BoxMutatingFunction};
204///
205/// fn apply_and_log<F: MutatingFunction<i32, i32>>(
206/// func: &F,
207/// value: i32
208/// ) -> i32 {
209/// let mut val = value;
210/// let result = func.apply(&mut val);
211/// println!("Modified: {} -> {}, returned: {}", value, val, result);
212/// result
213/// }
214///
215/// let incrementer = BoxMutatingFunction::new(|x: &mut i32| {
216/// *x += 1;
217/// *x
218/// });
219/// assert_eq!(apply_and_log(&incrementer, 5), 6);
220/// ```
221///
222/// ## Type Conversion
223///
224/// ```rust
225/// use qubit_function::MutatingFunction;
226///
227/// let closure = |x: &mut i32| {
228/// *x *= 2;
229/// *x
230/// };
231///
232/// // Convert to different ownership models
233/// let box_func = closure.into_box();
234/// // let rc_func = closure.into_rc(); // closure moved
235/// // let arc_func = closure.into_arc(); // closure moved
236/// ```
237///
238/// # Author
239///
240/// Haixing Hu
241pub trait MutatingFunction<T, R> {
242 /// Applies the function to the mutable reference and returns a result
243 ///
244 /// Executes an operation on the given mutable reference, potentially
245 /// modifying it, and returns a result value.
246 ///
247 /// # Parameters
248 ///
249 /// * `t` - A mutable reference to the input value
250 ///
251 /// # Returns
252 ///
253 /// The computed result value
254 ///
255 /// # Examples
256 ///
257 /// ```rust
258 /// use qubit_function::{MutatingFunction, BoxMutatingFunction};
259 ///
260 /// let func = BoxMutatingFunction::new(|x: &mut i32| {
261 /// let old = *x;
262 /// *x += 1;
263 /// old
264 /// });
265 ///
266 /// let mut value = 5;
267 /// let old_value = func.apply(&mut value);
268 /// assert_eq!(old_value, 5);
269 /// assert_eq!(value, 6);
270 /// ```
271 fn apply(&self, t: &mut T) -> R;
272
273 /// Convert this mutating function into a `BoxMutatingFunction<T, R>`.
274 ///
275 /// This consuming conversion takes ownership of `self` and returns a
276 /// boxed implementation that forwards calls to the original function.
277 /// Types that can provide a more efficient conversion may override the
278 /// default implementation.
279 ///
280 /// # Consumption
281 ///
282 /// This method consumes the function: the original value will no longer
283 /// be available after the call. For cloneable functions call `.clone()`
284 /// before converting if you need to retain the original instance.
285 ///
286 /// # Returns
287 ///
288 /// A `BoxMutatingFunction<T, R>` that forwards to the original function.
289 ///
290 /// # Examples
291 ///
292 /// ```rust
293 /// use qubit_function::MutatingFunction;
294 ///
295 /// let closure = |x: &mut i32| {
296 /// *x *= 2;
297 /// *x
298 /// };
299 /// let mut boxed = closure.into_box();
300 /// let mut value = 5;
301 /// assert_eq!(boxed.apply(&mut value), 10);
302 /// ```
303 fn into_box(self) -> BoxMutatingFunction<T, R>
304 where
305 Self: Sized + 'static,
306 T: 'static,
307 R: 'static,
308 {
309 BoxMutatingFunction::new(move |t| self.apply(t))
310 }
311
312 /// Convert this mutating function into an `RcMutatingFunction<T, R>`.
313 ///
314 /// This consuming conversion takes ownership of `self` and returns an
315 /// `Rc`-backed function that forwards calls to the original. Override to
316 /// provide a more direct or efficient conversion when available.
317 ///
318 /// # Consumption
319 ///
320 /// This method consumes the function. If you need to keep the original
321 /// instance, clone it prior to calling this method.
322 ///
323 /// # Returns
324 ///
325 /// An `RcMutatingFunction<T, R>` forwarding to the original function.
326 ///
327 /// # Examples
328 ///
329 /// ```rust
330 /// use qubit_function::MutatingFunction;
331 ///
332 /// let closure = |x: &mut i32| {
333 /// *x *= 2;
334 /// *x
335 /// };
336 /// let mut rc = closure.into_rc();
337 /// let mut value = 5;
338 /// assert_eq!(rc.apply(&mut value), 10);
339 /// ```
340 fn into_rc(self) -> RcMutatingFunction<T, R>
341 where
342 Self: Sized + 'static,
343 T: 'static,
344 R: 'static,
345 {
346 RcMutatingFunction::new(move |t| self.apply(t))
347 }
348
349 /// Convert this mutating function into an `ArcMutatingFunction<T, R>`.
350 ///
351 /// This consuming conversion takes ownership of `self` and returns an
352 /// `Arc`-wrapped, thread-safe function. Types may override the default
353 /// implementation to provide a more efficient conversion.
354 ///
355 /// # Consumption
356 ///
357 /// This method consumes the function. Clone the instance first if you
358 /// need to retain the original for further use.
359 ///
360 /// # Returns
361 ///
362 /// An `ArcMutatingFunction<T, R>` that forwards to the original
363 /// function.
364 ///
365 /// # Examples
366 ///
367 /// ```rust
368 /// use qubit_function::MutatingFunction;
369 ///
370 /// let closure = |x: &mut i32| {
371 /// *x *= 2;
372 /// *x
373 /// };
374 /// let mut arc = closure.into_arc();
375 /// let mut value = 5;
376 /// assert_eq!(arc.apply(&mut value), 10);
377 /// ```
378 fn into_arc(self) -> ArcMutatingFunction<T, R>
379 where
380 Self: Sized + Send + Sync + 'static,
381 T: Send + 'static,
382 R: Send + 'static,
383 {
384 ArcMutatingFunction::new(move |t| self.apply(t))
385 }
386
387 /// Consume the function and return an `Fn(&mut T) -> R` closure.
388 ///
389 /// The returned closure forwards calls to the original function and is
390 /// suitable for use with iterator adapters or other contexts expecting
391 /// closures.
392 ///
393 /// # Consumption
394 ///
395 /// This method consumes the function. The original instance will not be
396 /// available after calling this method.
397 ///
398 /// # Returns
399 ///
400 /// A closure implementing `Fn(&mut T) -> R` which forwards to the
401 /// original function.
402 ///
403 /// # Examples
404 ///
405 /// ```rust
406 /// use qubit_function::{MutatingFunction, BoxMutatingFunction};
407 ///
408 /// let func = BoxMutatingFunction::new(|x: &mut i32| {
409 /// *x *= 2;
410 /// *x
411 /// });
412 /// let closure = func.into_fn();
413 /// let mut value = 5;
414 /// assert_eq!(closure(&mut value), 10);
415 /// ```
416 fn into_fn(self) -> impl Fn(&mut T) -> R
417 where
418 Self: Sized + 'static,
419 {
420 move |t| self.apply(t)
421 }
422
423 /// Convert to MutatingFunctionOnce
424 ///
425 /// **⚠️ Consumes `self`**: The original function will be unavailable
426 /// after calling this method.
427 ///
428 /// Converts a reusable mutating function to a one-time function that
429 /// consumes itself on use. This enables passing `MutatingFunction` to
430 /// functions that require `MutatingFunctionOnce`.
431 ///
432 /// # Returns
433 ///
434 /// Returns a `BoxMutatingFunctionOnce<T, R>`
435 ///
436 /// # Examples
437 ///
438 /// ```rust
439 /// use qubit_function::{MutatingFunctionOnce, MutatingFunction,
440 /// BoxMutatingFunction};
441 ///
442 /// fn takes_once<F: MutatingFunctionOnce<i32, i32>>(func: F, value: &mut i32) {
443 /// let result = func.apply(value);
444 /// println!("Result: {}", result);
445 /// }
446 ///
447 /// let func = BoxMutatingFunction::new(|x: &mut i32| {
448 /// *x *= 2;
449 /// *x
450 /// });
451 /// let mut value = 5;
452 /// takes_once(func.into_once(), &mut value);
453 /// ```
454 fn into_once(self) -> BoxMutatingFunctionOnce<T, R>
455 where
456 Self: Sized + 'static,
457 T: 'static,
458 R: 'static,
459 {
460 BoxMutatingFunctionOnce::new(move |t| self.apply(t))
461 }
462
463 /// Create a non-consuming `BoxMutatingFunction<T, R>` that forwards to
464 /// `self`.
465 ///
466 /// The default implementation clones `self` (requires `Clone`) and
467 /// returns a boxed function that calls the cloned instance. Override this
468 /// method if a more efficient conversion exists.
469 ///
470 /// # Returns
471 ///
472 /// A `BoxMutatingFunction<T, R>` that forwards to a clone of `self`.
473 fn to_box(&self) -> BoxMutatingFunction<T, R>
474 where
475 Self: Sized + Clone + 'static,
476 T: 'static,
477 R: 'static,
478 {
479 self.clone().into_box()
480 }
481
482 /// Create a non-consuming `RcMutatingFunction<T, R>` that forwards to
483 /// `self`.
484 ///
485 /// The default implementation clones `self` (requires `Clone`) and
486 /// returns an `Rc`-backed function that forwards calls to the clone.
487 /// Override to provide a more direct or efficient conversion if needed.
488 ///
489 /// # Returns
490 ///
491 /// An `RcMutatingFunction<T, R>` that forwards to a clone of `self`.
492 fn to_rc(&self) -> RcMutatingFunction<T, R>
493 where
494 Self: Sized + Clone + 'static,
495 T: 'static,
496 R: '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 T: Send + 'static,
516 R: Send + 'static,
517 {
518 self.clone().into_arc()
519 }
520
521 /// Create a boxed `Fn(&mut T) -> R` closure that forwards to `self`.
522 ///
523 /// The default implementation clones `self` (requires `Clone`) and
524 /// returns a boxed closure that invokes the cloned instance. Override to
525 /// provide a more efficient conversion when possible.
526 ///
527 /// # Returns
528 ///
529 /// A closure implementing `Fn(&mut T) -> R` which forwards to the
530 /// original function.
531 fn to_fn(&self) -> impl Fn(&mut T) -> R
532 where
533 Self: Sized + Clone + 'static,
534 {
535 self.clone().into_fn()
536 }
537
538 /// Convert to MutatingFunctionOnce without consuming self
539 ///
540 /// **⚠️ Requires Clone**: This method requires `Self` to implement `Clone`.
541 /// Clones the current function and converts the clone to a one-time function.
542 ///
543 /// # Returns
544 ///
545 /// Returns a `BoxMutatingFunctionOnce<T, R>`
546 ///
547 /// # Examples
548 ///
549 /// ```rust
550 /// use qubit_function::{MutatingFunctionOnce, MutatingFunction,
551 /// BoxMutatingFunction};
552 ///
553 /// fn takes_once<F: MutatingFunctionOnce<i32, i32>>(func: F, value: &mut i32) {
554 /// let result = func.apply(value);
555 /// println!("Result: {}", result);
556 /// }
557 ///
558 /// let func = BoxMutatingFunction::new(|x: &mut i32| {
559 /// *x *= 2;
560 /// *x
561 /// });
562 /// let mut value = 5;
563 /// takes_once(func.to_once(), &mut value);
564 /// ```
565 fn to_once(&self) -> BoxMutatingFunctionOnce<T, R>
566 where
567 Self: Clone + 'static,
568 T: 'static,
569 R: 'static,
570 {
571 self.clone().into_once()
572 }
573}
574
575// =======================================================================
576// 3. BoxMutatingFunction - Single Ownership Implementation
577// =======================================================================
578
579/// BoxMutatingFunction struct
580///
581/// A mutating function implementation based on `Box<dyn Fn(&mut T) -> R>`
582/// for single ownership scenarios. This is the simplest and most efficient
583/// mutating function type when sharing is not required.
584///
585/// # Features
586///
587/// - **Single Ownership**: Not cloneable, ownership moves on use
588/// - **Zero Overhead**: No reference counting or locking
589/// - **Stateless**: Cannot modify captured environment (uses `Fn` not
590/// `FnMut`)
591/// - **Builder Pattern**: Method chaining consumes `self` naturally
592/// - **Factory Methods**: Convenient constructors for common patterns
593///
594/// # Use Cases
595///
596/// Choose `BoxMutatingFunction` when:
597/// - The function is used for stateless operations
598/// - Building pipelines where ownership naturally flows
599/// - No need to share the function across contexts
600/// - Performance is critical and no sharing overhead is acceptable
601///
602/// # Performance
603///
604/// `BoxMutatingFunction` has the best performance among the three function
605/// types:
606/// - No reference counting overhead
607/// - No lock acquisition or runtime borrow checking
608/// - Direct function call through vtable
609/// - Minimal memory footprint (single pointer)
610///
611/// # Examples
612///
613/// ```rust
614/// use qubit_function::{MutatingFunction, BoxMutatingFunction};
615///
616/// let func = BoxMutatingFunction::new(|x: &mut i32| {
617/// *x *= 2;
618/// *x
619/// });
620/// let mut value = 5;
621/// assert_eq!(func.apply(&mut value), 10);
622/// assert_eq!(value, 10);
623/// ```
624///
625/// # Author
626///
627/// Haixing Hu
628pub struct BoxMutatingFunction<T, R> {
629 function: Box<dyn Fn(&mut T) -> R>,
630 name: Option<String>,
631}
632
633impl<T, R> BoxMutatingFunction<T, R> {
634 // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
635 impl_function_common_methods!(
636 BoxMutatingFunction<T, R>,
637 (Fn(&mut T) -> R + 'static),
638 |f| Box::new(f)
639 );
640
641 // Generates: when(), and_then(), compose()
642 impl_box_function_methods!(
643 BoxMutatingFunction<T, R>,
644 BoxConditionalMutatingFunction,
645 Function // chains a non-mutating function after this mutating function
646 );
647}
648
649// Generates: Debug and Display implementations for BoxMutatingFunction<T, R>
650impl_function_debug_display!(BoxMutatingFunction<T, R>);
651
652// Generates: identity() method for BoxMutatingFunction<T, T>
653impl_function_identity_method!(BoxMutatingFunction<T, T>, mutating);
654
655// Implement MutatingFunction trait for BoxMutatingFunction<T, R>
656impl<T, R> MutatingFunction<T, R> for BoxMutatingFunction<T, R> {
657 fn apply(&self, t: &mut T) -> R {
658 (self.function)(t)
659 }
660
661 // Generates: into_box(), into_rc(), into_fn(), into_once()
662 impl_box_conversions!(
663 BoxMutatingFunction<T, R>,
664 RcMutatingFunction,
665 Fn(&mut T) -> R,
666 BoxMutatingFunctionOnce
667 );
668}
669
670// =======================================================================
671// 4. RcMutatingFunction - Single-Threaded Shared Ownership
672// =======================================================================
673
674/// RcMutatingFunction struct
675///
676/// A mutating function implementation based on `Rc<dyn Fn(&mut T) -> R>` for
677/// single-threaded shared ownership scenarios. This type allows multiple
678/// references to the same function without the overhead of thread safety.
679///
680/// # Features
681///
682/// - **Shared Ownership**: Cloneable via `Rc`, multiple owners allowed
683/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
684/// - **Stateless**: Cannot modify captured environment (uses `Fn` not
685/// `FnMut`)
686/// - **Chainable**: Method chaining via `&self` (non-consuming)
687/// - **Performance**: More efficient than `ArcMutatingFunction` (no locking)
688///
689/// # Use Cases
690///
691/// Choose `RcMutatingFunction` when:
692/// - The function needs to be shared within a single thread for stateless
693/// operations
694/// - Thread safety is not required
695/// - Performance is important (avoiding lock overhead)
696///
697/// # Examples
698///
699/// ```rust
700/// use qubit_function::{MutatingFunction, RcMutatingFunction};
701///
702/// let func = RcMutatingFunction::new(|x: &mut i32| {
703/// *x *= 2;
704/// *x
705/// });
706/// let clone = func.clone();
707///
708/// let mut value = 5;
709/// assert_eq!(func.apply(&mut value), 10);
710/// ```
711///
712/// # Author
713///
714/// Haixing Hu
715pub struct RcMutatingFunction<T, R> {
716 function: Rc<dyn Fn(&mut T) -> R>,
717 name: Option<String>,
718}
719
720impl<T, R> RcMutatingFunction<T, R> {
721 // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
722 impl_function_common_methods!(
723 RcMutatingFunction<T, R>,
724 (Fn(&mut T) -> R + 'static),
725 |f| Rc::new(f)
726 );
727
728 // Generates: when(), and_then(), compose()
729 impl_shared_function_methods!(
730 RcMutatingFunction<T, R>,
731 RcConditionalMutatingFunction,
732 into_rc,
733 Function, // chains a non-mutating function after this mutating function
734 'static
735 );
736}
737
738// Generates: Clone implementation for RcMutatingFunction<T, R>
739impl_function_clone!(RcMutatingFunction<T, R>);
740
741// Generates: Debug and Display implementations for RcMutatingFunction<T, R>
742impl_function_debug_display!(RcMutatingFunction<T, R>);
743
744// Generates: identity() method for RcMutatingFunction<T, T>
745impl_function_identity_method!(RcMutatingFunction<T, T>, mutating);
746
747impl<T, R> MutatingFunction<T, R> for RcMutatingFunction<T, R> {
748 fn apply(&self, input: &mut T) -> R {
749 (self.function)(input)
750 }
751
752 // Use macro to implement conversion methods
753 impl_rc_conversions!(
754 RcMutatingFunction<T, R>,
755 BoxMutatingFunction,
756 BoxMutatingFunctionOnce,
757 Fn(input: &mut T) -> R
758 );
759}
760
761// =======================================================================
762// 5. ArcMutatingFunction - Thread-Safe Shared Ownership
763// =======================================================================
764
765/// ArcMutatingFunction struct
766///
767/// A mutating function implementation based on
768/// `Arc<dyn Fn(&mut T) -> R + Send + Sync>` for thread-safe shared ownership
769/// scenarios. This type allows the function to be safely shared and used
770/// across multiple threads.
771///
772/// # Features
773///
774/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
775/// - **Thread-Safe**: Implements `Send + Sync`, safe for concurrent use
776/// - **Stateless**: Cannot modify captured environment (uses `Fn` not
777/// `FnMut`)
778/// - **Chainable**: Method chaining via `&self` (non-consuming)
779///
780/// # Use Cases
781///
782/// Choose `ArcMutatingFunction` when:
783/// - The function needs to be shared across multiple threads for stateless
784/// operations
785/// - Concurrent task processing (e.g., thread pools)
786/// - Thread safety is required (Send + Sync)
787///
788/// # Examples
789///
790/// ```rust
791/// use qubit_function::{MutatingFunction, ArcMutatingFunction};
792///
793/// let func = ArcMutatingFunction::new(|x: &mut i32| {
794/// *x *= 2;
795/// *x
796/// });
797/// let clone = func.clone();
798///
799/// let mut value = 5;
800/// assert_eq!(func.apply(&mut value), 10);
801/// ```
802///
803/// # Author
804///
805/// Haixing Hu
806pub struct ArcMutatingFunction<T, R> {
807 function: Arc<dyn Fn(&mut T) -> R + Send + Sync>,
808 name: Option<String>,
809}
810
811impl<T, R> ArcMutatingFunction<T, R> {
812 // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
813 impl_function_common_methods!(
814 ArcMutatingFunction<T, R>,
815 (Fn(&mut T) -> R + Send + Sync + 'static),
816 |f| Arc::new(f)
817 );
818
819 // Generates: when(), and_then(), compose()
820 impl_shared_function_methods!(
821 ArcMutatingFunction<T, R>,
822 ArcConditionalMutatingFunction,
823 into_arc,
824 Function, // chains a non-mutating function after this mutating function
825 Send + Sync + 'static
826 );
827}
828
829// Generates: Clone implementation for ArcMutatingFunction<T, R>
830impl_function_clone!(ArcMutatingFunction<T, R>);
831
832// Generates: Debug and Display implementations for ArcMutatingFunction<T, R>
833impl_function_debug_display!(ArcMutatingFunction<T, R>);
834
835// Generates: identity() method for ArcMutatingFunction<T, T>
836impl_function_identity_method!(ArcMutatingFunction<T, T>, mutating);
837
838impl<T, R> MutatingFunction<T, R> for ArcMutatingFunction<T, R> {
839 fn apply(&self, input: &mut T) -> R {
840 (self.function)(input)
841 }
842
843 // Use macro to implement conversion methods
844 impl_arc_conversions!(
845 ArcMutatingFunction<T, R>,
846 BoxMutatingFunction,
847 RcMutatingFunction,
848 BoxMutatingFunctionOnce,
849 Fn(input: &mut T) -> R
850 );
851}
852
853// =======================================================================
854// 6. Implement MutatingFunction trait for closures
855// =======================================================================
856
857impl_closure_trait!(
858 MutatingFunction<T, R>,
859 apply,
860 BoxMutatingFunctionOnce,
861 Fn(input: &mut T) -> R
862);
863
864// =======================================================================
865// 7. Provide extension methods for closures
866// =======================================================================
867
868// Generates: FnFunctionOps trait and blanket implementation
869impl_fn_ops_trait!(
870 (Fn(&mut T) -> R),
871 FnMutatingFunctionOps,
872 BoxMutatingFunction,
873 Function, // chains a non-mutating function after this mutating function
874 BoxConditionalMutatingFunction
875);
876
877// ============================================================================
878// BoxConditionalMutatingFunction - Box-based Conditional Mutating Function
879// ============================================================================
880
881/// BoxConditionalMutatingFunction struct
882///
883/// A conditional function that only executes when a predicate is satisfied.
884/// Uses `BoxMutatingFunction` and `BoxPredicate` for single ownership semantics.
885///
886/// This type is typically created by calling `BoxMutatingFunction::when()` and is
887/// designed to work with the `or_else()` method to create if-then-else logic.
888///
889/// # Features
890///
891/// - **Single Ownership**: Not cloneable, consumes `self` on use
892/// - **Conditional Execution**: Only transforms when predicate returns `true`
893/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
894/// - **Implements Function**: Can be used anywhere a `Function` is expected
895///
896/// # Examples
897///
898/// ## With or_else Branch
899///
900/// ```rust
901/// use qubit_function::{MutatingFunction, BoxMutatingFunction};
902///
903/// let double = BoxMutatingFunction::new(|x: &mut i32| x * 2);
904/// let negate = BoxMutatingFunction::new(|x: &mut i32| -x);
905/// let conditional = double.when(|x: &i32| *x > 0).or_else(negate);
906///
907/// assert_eq!(conditional.apply(5), 10); // when branch executed
908/// assert_eq!(conditional.apply(-5), 5); // or_else branch executed
909/// ```
910///
911/// # Author
912///
913/// Haixing Hu
914pub struct BoxConditionalMutatingFunction<T, R> {
915 function: BoxMutatingFunction<T, R>,
916 predicate: BoxPredicate<T>,
917}
918
919// Use macro to generate conditional function implementations
920impl_box_conditional_function!(
921 BoxConditionalMutatingFunction<T, R>,
922 BoxMutatingFunction,
923 MutatingFunction
924);
925
926// Use macro to generate conditional function debug and display implementations
927impl_conditional_function_debug_display!(BoxConditionalMutatingFunction<T, R>);
928
929// ============================================================================
930// RcConditionalMutatingFunction - Rc-based Conditional Mutating Function
931// ============================================================================
932
933/// RcConditionalMutatingFunction struct
934///
935/// A single-threaded conditional function that only executes when a
936/// predicate is satisfied. Uses `RcMutatingFunction` and `RcPredicate` for shared
937/// ownership within a single thread.
938///
939/// This type is typically created by calling `RcMutatingFunction::when()` and is
940/// designed to work with the `or_else()` method to create if-then-else logic.
941///
942/// # Features
943///
944/// - **Shared Ownership**: Cloneable via `Rc`, multiple owners allowed
945/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
946/// - **Conditional Execution**: Only transforms when predicate returns `true`
947/// - **No Lock Overhead**: More efficient than `ArcConditionalFunction`
948///
949/// # Examples
950///
951/// ```rust
952/// use qubit_function::{MutatingFunction, RcMutatingFunction};
953///
954/// let double = RcMutatingFunction::new(|x: &mut i32| x * 2);
955/// let identity = RcMutatingFunction::<i32, i32>::identity();
956/// let conditional = double.when(|x: &i32| *x > 0).or_else(identity);
957///
958/// let conditional_clone = conditional.clone();
959///
960/// assert_eq!(conditional.apply(5), 10);
961/// assert_eq!(conditional_clone.apply(-5), -5);
962/// ```
963///
964/// # Author
965///
966/// Haixing Hu
967pub struct RcConditionalMutatingFunction<T, R> {
968 function: RcMutatingFunction<T, R>,
969 predicate: RcPredicate<T>,
970}
971
972// Use macro to generate conditional function implementations
973impl_shared_conditional_function!(
974 RcConditionalMutatingFunction<T, R>,
975 RcMutatingFunction,
976 MutatingFunction,
977 'static
978);
979
980// Use macro to generate conditional function clone implementations
981impl_conditional_function_clone!(RcConditionalMutatingFunction<T, R>);
982
983// Use macro to generate conditional function debug and display implementations
984impl_conditional_function_debug_display!(RcConditionalMutatingFunction<T, R>);
985
986// ============================================================================
987// ArcConditionalMutatingFunction - Arc-based Conditional Mutating Function
988// ============================================================================
989
990/// ArcConditionalMutatingFunction struct
991///
992/// A thread-safe conditional function that only executes when a predicate is
993/// satisfied. Uses `ArcMutatingFunction` and `ArcPredicate` for shared ownership
994/// across threads.
995///
996/// This type is typically created by calling `ArcMutatingFunction::when()` and is
997/// designed to work with the `or_else()` method to create if-then-else logic.
998///
999/// # Features
1000///
1001/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
1002/// - **Thread-Safe**: Implements `Send + Sync`, safe for concurrent use
1003/// - **Conditional Execution**: Only transforms when predicate returns `true`
1004/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
1005///
1006/// # Examples
1007///
1008/// ```rust
1009/// use qubit_function::{MutatingFunction, ArcMutatingFunction};
1010///
1011/// let double = ArcMutatingFunction::new(|x: &mut i32| x * 2);
1012/// let identity = ArcMutatingFunction::<i32, i32>::identity();
1013/// let conditional = double.when(|x: &i32| *x > 0).or_else(identity);
1014///
1015/// let conditional_clone = conditional.clone();
1016///
1017/// assert_eq!(conditional.apply(5), 10);
1018/// assert_eq!(conditional_clone.apply(-5), -5);
1019/// ```
1020///
1021/// # Author
1022///
1023/// Haixing Hu
1024pub struct ArcConditionalMutatingFunction<T, R> {
1025 function: ArcMutatingFunction<T, R>,
1026 predicate: ArcPredicate<T>,
1027}
1028
1029// Use macro to generate conditional function implementations
1030impl_shared_conditional_function!(
1031 ArcConditionalMutatingFunction<T, R>,
1032 ArcMutatingFunction,
1033 MutatingFunction,
1034 Send + Sync + 'static
1035);
1036
1037// Use macro to generate conditional function clone implementations
1038impl_conditional_function_clone!(ArcConditionalMutatingFunction<T, R>);
1039
1040// Use macro to generate conditional function debug and display implementations
1041impl_conditional_function_debug_display!(ArcConditionalMutatingFunction<T, R>);