prism3_function/
mutator_once.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025.
4 *    3-Prism Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # MutatorOnce Types
10//!
11//! Provides Java-style one-time `Mutator` interface implementations for performing
12//! operations that consume self and modify the input value.
13//!
14//! This module provides a unified `MutatorOnce` trait and a Box-based single
15//! ownership implementation:
16//!
17//! - **`BoxMutatorOnce<T>`**: Box-based single ownership implementation for
18//!   one-time use scenarios
19//!
20//! # Design Philosophy
21//!
22//! The key difference between `MutatorOnce` and `Mutator`:
23//!
24//! - **Mutator**: `&mut self`, can be called multiple times, uses `FnMut(&mut T)`
25//! - **MutatorOnce**: `self`, can only be called once, uses `FnOnce(&mut T)`
26//!
27//! ## MutatorOnce vs Mutator
28//!
29//! | Feature | Mutator | MutatorOnce |
30//! |---------|---------|-------------|
31//! | **Self Parameter** | `&mut self` | `self` |
32//! | **Call Count** | Multiple | Once |
33//! | **Closure Type** | `FnMut(&mut T)` | `FnOnce(&mut T)` |
34//! | **Use Cases** | Repeatable modifications | One-time resource transfers, init callbacks |
35//!
36//! # Why MutatorOnce?
37//!
38//! Core value of MutatorOnce:
39//!
40//! 1. **Store FnOnce closures**: Allows moving captured variables
41//! 2. **Delayed execution**: Store in data structures, execute later
42//! 3. **Resource transfer**: Suitable for scenarios requiring ownership transfer
43//!
44//! # Why Only Box Variant?
45//!
46//! - **Arc/Rc conflicts with FnOnce semantics**: FnOnce can only be called once,
47//!   while shared ownership implies multiple references
48//! - **Box is perfect match**: Single ownership aligns perfectly with one-time
49//!   call semantics
50//!
51//! # Use Cases
52//!
53//! ## BoxMutatorOnce
54//!
55//! - Post-initialization callbacks (moving data)
56//! - Resource transfer (moving Vec, String, etc.)
57//! - One-time complex operations (requiring moved capture variables)
58//!
59//! # Examples
60//!
61//! ## Basic Usage
62//!
63//! ```rust
64//! use prism3_function::{BoxMutatorOnce, MutatorOnce};
65//!
66//! let data = vec![1, 2, 3];
67//! let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
68//!     x.extend(data); // Move data
69//! });
70//!
71//! let mut target = vec![0];
72//! mutator.mutate(&mut target);
73//! assert_eq!(target, vec![0, 1, 2, 3]);
74//! ```
75//!
76//! ## Method Chaining
77//!
78//! ```rust
79//! use prism3_function::{BoxMutatorOnce, MutatorOnce};
80//!
81//! let data1 = vec![1, 2];
82//! let data2 = vec![3, 4];
83//!
84//! let chained = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
85//!     x.extend(data1);
86//! })
87//! .and_then(move |x: &mut Vec<i32>| {
88//!     x.extend(data2);
89//! });
90//!
91//! let mut target = vec![0];
92//! chained.mutate(&mut target);
93//! assert_eq!(target, vec![0, 1, 2, 3, 4]);
94//! ```
95//!
96//! ## Initialization Callback
97//!
98//! ```rust
99//! use prism3_function::BoxMutatorOnce;
100//!
101//! struct Initializer {
102//!     on_complete: Option<BoxMutatorOnce<Vec<i32>>>,
103//! }
104//!
105//! impl Initializer {
106//!     fn new<F>(callback: F) -> Self
107//!     where
108//!         F: FnOnce(&mut Vec<i32>) + 'static
109//!     {
110//!         Self {
111//!             on_complete: Some(BoxMutatorOnce::new(callback))
112//!         }
113//!     }
114//!
115//!     fn run(mut self, data: &mut Vec<i32>) {
116//!         // Execute initialization logic
117//!         data.push(42);
118//!
119//!         // Call callback
120//!         if let Some(callback) = self.on_complete.take() {
121//!             callback.mutate(data);
122//!         }
123//!     }
124//! }
125//!
126//! let data_to_add = vec![1, 2, 3];
127//! let init = Initializer::new(move |x| {
128//!     x.extend(data_to_add); // Move data_to_add
129//! });
130//!
131//! let mut result = Vec::new();
132//! init.run(&mut result);
133//! assert_eq!(result, vec![42, 1, 2, 3]);
134//! ```
135//!
136//! # Author
137//!
138//! Haixing Hu
139
140use crate::predicate::{BoxPredicate, Predicate};
141
142// ============================================================================
143// 1. MutatorOnce Trait - One-time Mutator Interface
144// ============================================================================
145
146/// MutatorOnce trait - One-time mutator interface
147///
148/// Defines the core behavior of all one-time mutator types. Performs operations
149/// that consume self and modify the input value.
150///
151/// This trait is automatically implemented by:
152/// - All closures implementing `FnOnce(&mut T)`
153/// - `BoxMutatorOnce<T>`
154///
155/// # Design Rationale
156///
157/// This trait provides a unified abstraction for one-time mutation operations.
158/// The key difference from `Mutator`:
159/// - `Mutator` uses `&mut self`, can be called multiple times
160/// - `MutatorOnce` uses `self`, can only be called once
161///
162/// # Features
163///
164/// - **Unified Interface**: All one-time mutators share the same `mutate`
165///   method signature
166/// - **Automatic Implementation**: Closures automatically implement this
167///   trait with zero overhead
168/// - **Type Conversions**: Provides `into_box` method for type conversion
169/// - **Generic Programming**: Write functions that work with any one-time
170///   mutator type
171///
172/// # Examples
173///
174/// ## Generic Function
175///
176/// ```rust
177/// use prism3_function::{MutatorOnce, BoxMutatorOnce};
178///
179/// fn apply_once<M: MutatorOnce<Vec<i32>>>(
180///     mutator: M,
181///     initial: Vec<i32>
182/// ) -> Vec<i32> {
183///     let mut val = initial;
184///     mutator.mutate(&mut val);
185///     val
186/// }
187///
188/// let data = vec![1, 2, 3];
189/// let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
190///     x.extend(data);
191/// });
192/// let result = apply_once(mutator, vec![0]);
193/// assert_eq!(result, vec![0, 1, 2, 3]);
194/// ```
195///
196/// ## Type Conversion
197///
198/// ```rust
199/// use prism3_function::MutatorOnce;
200///
201/// let data = vec![1, 2, 3];
202/// let closure = move |x: &mut Vec<i32>| x.extend(data);
203/// let box_mutator = closure.into_box();
204/// ```
205///
206/// # Author
207///
208/// Haixing Hu
209pub trait MutatorOnce<T> {
210    /// Performs the one-time mutation operation
211    ///
212    /// Consumes self and executes an operation on the given mutable reference.
213    /// The operation typically modifies the input value or produces side effects,
214    /// and can only be called once.
215    ///
216    /// # Parameters
217    ///
218    /// * `value` - A mutable reference to the value to be mutated
219    ///
220    /// # Examples
221    ///
222    /// ```rust
223    /// use prism3_function::{MutatorOnce, BoxMutatorOnce};
224    ///
225    /// let data = vec![1, 2, 3];
226    /// let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
227    ///     x.extend(data);
228    /// });
229    ///
230    /// let mut target = vec![0];
231    /// mutator.mutate(&mut target);
232    /// assert_eq!(target, vec![0, 1, 2, 3]);
233    /// ```
234    fn mutate(self, value: &mut T);
235
236    /// Converts to BoxMutatorOnce
237    ///
238    /// **⚠️ Consumes `self`**: The original mutator becomes unavailable
239    /// after calling this method.
240    ///
241    /// Converts the current mutator to `BoxMutatorOnce<T>`.
242    ///
243    /// # Ownership
244    ///
245    /// This method **consumes** the mutator (takes ownership of `self`).
246    /// After calling this method, the original mutator is no longer
247    /// available.
248    ///
249    /// # Returns
250    ///
251    /// Returns the wrapped `BoxMutatorOnce<T>`
252    ///
253    /// # Examples
254    ///
255    /// ```rust
256    /// use prism3_function::MutatorOnce;
257    ///
258    /// let data = vec![1, 2, 3];
259    /// let closure = move |x: &mut Vec<i32>| x.extend(data);
260    /// let box_mutator = closure.into_box();
261    /// ```
262    fn into_box(self) -> BoxMutatorOnce<T>
263    where
264        Self: Sized + 'static,
265        T: 'static;
266}
267
268// ============================================================================
269// 2. BoxMutatorOnce - Single Ownership Implementation
270// ============================================================================
271
272/// BoxMutatorOnce struct
273///
274/// A one-time mutator implementation based on `Box<dyn FnOnce(&mut T)>` for
275/// single ownership scenarios. This is the only MutatorOnce implementation type
276/// because FnOnce conflicts with shared ownership semantics.
277///
278/// # Features
279///
280/// - **Single Ownership**: Not cloneable, consumes self on use
281/// - **Zero Overhead**: No reference counting or locking
282/// - **Move Semantics**: Can capture and move variables
283/// - **Method Chaining**: Compose multiple operations via `and_then`
284///
285/// # Use Cases
286///
287/// Choose `BoxMutatorOnce` when:
288/// - Need to store FnOnce closures (with moved captured variables)
289/// - One-time resource transfer operations
290/// - Post-initialization callbacks
291/// - Complex operations requiring ownership transfer
292///
293/// # Performance
294///
295/// `BoxMutatorOnce` performance characteristics:
296/// - No reference counting overhead
297/// - No lock acquisition or runtime borrow checking
298/// - Direct function call through vtable
299/// - Minimal memory footprint (single pointer)
300///
301/// # Why No Arc/Rc Variants?
302///
303/// FnOnce can only be called once, which conflicts with Arc/Rc shared ownership
304/// semantics:
305/// - Arc/Rc implies multiple owners might need to call
306/// - FnOnce is consumed after calling, cannot be called again
307/// - This semantic incompatibility makes Arc/Rc variants meaningless
308///
309/// # Examples
310///
311/// ## Basic Usage
312///
313/// ```rust
314/// use prism3_function::{MutatorOnce, BoxMutatorOnce};
315///
316/// let data = vec![1, 2, 3];
317/// let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
318///     x.extend(data); // Move data
319/// });
320///
321/// let mut target = vec![0];
322/// mutator.mutate(&mut target);
323/// assert_eq!(target, vec![0, 1, 2, 3]);
324/// ```
325///
326/// ## Method Chaining
327///
328/// ```rust
329/// use prism3_function::{MutatorOnce, BoxMutatorOnce};
330///
331/// let data1 = vec![1, 2];
332/// let data2 = vec![3, 4];
333///
334/// let chained = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
335///     x.extend(data1);
336/// })
337/// .and_then(move |x: &mut Vec<i32>| {
338///     x.extend(data2);
339/// });
340///
341/// let mut target = vec![0];
342/// chained.mutate(&mut target);
343/// assert_eq!(target, vec![0, 1, 2, 3, 4]);
344/// ```
345///
346/// # Author
347///
348/// Haixing Hu
349pub struct BoxMutatorOnce<T> {
350    func: Box<dyn FnOnce(&mut T)>,
351}
352
353impl<T> BoxMutatorOnce<T>
354where
355    T: 'static,
356{
357    /// Creates a new BoxMutatorOnce
358    ///
359    /// # Parameters
360    ///
361    /// * `f` - The closure to wrap
362    ///
363    /// # Returns
364    ///
365    /// Returns a new `BoxMutatorOnce<T>` instance
366    ///
367    /// # Examples
368    ///
369    /// ```rust
370    /// use prism3_function::{MutatorOnce, BoxMutatorOnce};
371    ///
372    /// let data = String::from("world");
373    /// let mutator = BoxMutatorOnce::new(move |x: &mut String| {
374    ///     x.push_str(" ");
375    ///     x.push_str(&data); // Move data
376    /// });
377    ///
378    /// let mut target = String::from("hello");
379    /// mutator.mutate(&mut target);
380    /// assert_eq!(target, "hello world");
381    /// ```
382    pub fn new<F>(f: F) -> Self
383    where
384        F: FnOnce(&mut T) + 'static,
385    {
386        BoxMutatorOnce { func: Box::new(f) }
387    }
388
389    /// Creates a no-op mutator
390    ///
391    /// Returns a mutator that performs no operation.
392    ///
393    /// # Returns
394    ///
395    /// Returns a no-op mutator
396    ///
397    /// # Examples
398    ///
399    /// ```rust
400    /// use prism3_function::{MutatorOnce, BoxMutatorOnce};
401    ///
402    /// let noop = BoxMutatorOnce::<i32>::noop();
403    /// let mut value = 42;
404    /// noop.mutate(&mut value);
405    /// assert_eq!(value, 42); // Value unchanged
406    /// ```
407    pub fn noop() -> Self {
408        BoxMutatorOnce::new(|_| {})
409    }
410
411    /// Chains another mutator in sequence
412    ///
413    /// Returns a new mutator that first executes the current operation, then
414    /// executes the next operation. Consumes self.
415    ///
416    /// # Parameters
417    ///
418    /// * `next` - The mutator to execute after the current operation. **Note:
419    ///   This parameter is passed by value and will transfer ownership.** Since
420    ///   `BoxMutatorOnce` cannot be cloned, the parameter will be consumed.
421    ///   Can be:
422    ///   - A closure: `|x: &mut T|`
423    ///   - A `BoxMutatorOnce<T>`
424    ///   - Any type implementing `MutatorOnce<T>`
425    ///
426    /// # Returns
427    ///
428    /// Returns a new composed `BoxMutatorOnce<T>`
429    ///
430    /// # Examples
431    ///
432    /// ```rust
433    /// use prism3_function::{MutatorOnce, BoxMutatorOnce};
434    ///
435    /// let data1 = vec![1, 2];
436    /// let data2 = vec![3, 4];
437    /// let data3 = vec![5, 6];
438    ///
439    /// let chained = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
440    ///     x.extend(data1);
441    /// })
442    /// .and_then(move |x: &mut Vec<i32>| {
443    ///     x.extend(data2);
444    /// })
445    /// .and_then(move |x: &mut Vec<i32>| {
446    ///     x.extend(data3);
447    /// });
448    ///
449    /// let mut target = vec![0];
450    /// chained.mutate(&mut target);
451    /// assert_eq!(target, vec![0, 1, 2, 3, 4, 5, 6]);
452    /// ```
453    pub fn and_then<C>(self, next: C) -> Self
454    where
455        C: MutatorOnce<T> + 'static,
456    {
457        let first = self.func;
458        BoxMutatorOnce::new(move |t| {
459            first(t);
460            next.mutate(t);
461        })
462    }
463
464    /// Creates a conditional mutator
465    ///
466    /// Returns a mutator that only executes when a predicate is satisfied.
467    ///
468    /// # Parameters
469    ///
470    /// * `predicate` - The condition to check. **Note: This parameter is passed
471    ///   by value and will transfer ownership.** If you need to preserve the
472    ///   original predicate, clone it first (if it implements `Clone`). Can be:
473    ///   - A closure: `|x: &T| -> bool`
474    ///   - A function pointer: `fn(&T) -> bool`
475    ///   - A `BoxPredicate<T>`
476    ///   - An `RcPredicate<T>`
477    ///   - An `ArcPredicate<T>`
478    ///   - Any type implementing `Predicate<T>`
479    ///
480    /// # Returns
481    ///
482    /// Returns `BoxConditionalMutatorOnce<T>`
483    ///
484    /// # Examples
485    ///
486    /// ## Using a closure
487    ///
488    /// ```rust
489    /// use prism3_function::{MutatorOnce, BoxMutatorOnce};
490    ///
491    /// let data = vec![1, 2, 3];
492    /// let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
493    ///     x.extend(data);
494    /// });
495    /// let conditional = mutator.when(|x: &Vec<i32>| !x.is_empty());
496    ///
497    /// let mut target = vec![0];
498    /// conditional.mutate(&mut target);
499    /// assert_eq!(target, vec![0, 1, 2, 3]);
500    ///
501    /// let mut empty = Vec::new();
502    /// let data2 = vec![4, 5];
503    /// let mutator2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
504    ///     x.extend(data2);
505    /// });
506    /// let conditional2 = mutator2.when(|x: &Vec<i32>| x.len() > 5);
507    /// conditional2.mutate(&mut empty);
508    /// assert_eq!(empty, Vec::<i32>::new()); // Unchanged
509    /// ```
510    ///
511    /// ## Preserving predicate with clone
512    ///
513    /// ```rust
514    /// use prism3_function::{MutatorOnce, BoxMutatorOnce, RcPredicate};
515    ///
516    /// let data = vec![1, 2, 3];
517    /// let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
518    ///     x.extend(data);
519    /// });
520    /// let predicate = RcPredicate::new(|x: &Vec<i32>| !x.is_empty());
521    ///
522    /// // Clone to preserve original predicate
523    /// let conditional = mutator.when(predicate.clone());
524    ///
525    /// let mut target = vec![0];
526    /// conditional.mutate(&mut target);
527    /// assert_eq!(target, vec![0, 1, 2, 3]);
528    ///
529    /// // Original predicate still usable
530    /// assert!(predicate.test(&vec![1, 2]));
531    /// ```
532    ///
533    /// ## Using composed predicate
534    ///
535    /// ```rust
536    /// use prism3_function::{MutatorOnce, BoxMutatorOnce};
537    /// use prism3_function::predicate::{Predicate, FnPredicateOps};
538    ///
539    /// let pred = (|x: &Vec<i32>| !x.is_empty())
540    ///     .and(|x: &Vec<i32>| x.len() < 10);
541    /// let data = vec![1, 2, 3];
542    /// let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
543    ///     x.extend(data);
544    /// });
545    /// let conditional = mutator.when(pred);
546    ///
547    /// let mut target = vec![0];
548    /// conditional.mutate(&mut target);
549    /// assert_eq!(target, vec![0, 1, 2, 3]);
550    /// ```
551    pub fn when<P>(self, predicate: P) -> BoxConditionalMutatorOnce<T>
552    where
553        P: Predicate<T> + 'static,
554    {
555        BoxConditionalMutatorOnce {
556            mutator: self,
557            predicate: predicate.into_box(),
558        }
559    }
560}
561
562impl<T> MutatorOnce<T> for BoxMutatorOnce<T> {
563    fn mutate(self, value: &mut T) {
564        (self.func)(value)
565    }
566
567    fn into_box(self) -> BoxMutatorOnce<T>
568    where
569        T: 'static,
570    {
571        self
572    }
573}
574
575// ============================================================================
576// 3. BoxConditionalMutatorOnce - Box-based Conditional Mutator
577// ============================================================================
578
579/// BoxConditionalMutatorOnce struct
580///
581/// A conditional one-time mutator that only executes when a predicate is satisfied.
582/// Uses `BoxMutatorOnce` and `BoxPredicate` for single ownership semantics.
583///
584/// This type is typically created by calling `BoxMutatorOnce::when()` and is
585/// designed to work with the `or_else()` method to create if-then-else logic.
586///
587/// # Features
588///
589/// - **Single Ownership**: Not cloneable, consumes `self` on use
590/// - **Conditional Execution**: Only mutates when predicate returns `true`
591/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
592/// - **Implements MutatorOnce**: Can be used anywhere a `MutatorOnce` is expected
593///
594/// # Examples
595///
596/// ## Basic Conditional Execution
597///
598/// ```rust
599/// use prism3_function::{MutatorOnce, BoxMutatorOnce};
600///
601/// let data = vec![1, 2, 3];
602/// let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
603///     x.extend(data);
604/// });
605/// let conditional = mutator.when(|x: &Vec<i32>| !x.is_empty());
606///
607/// let mut target = vec![0];
608/// conditional.mutate(&mut target);
609/// assert_eq!(target, vec![0, 1, 2, 3]); // Executed
610///
611/// let mut empty = Vec::new();
612/// let data2 = vec![4, 5];
613/// let mutator2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
614///     x.extend(data2);
615/// });
616/// let conditional2 = mutator2.when(|x: &Vec<i32>| x.len() > 5);
617/// conditional2.mutate(&mut empty);
618/// assert_eq!(empty, Vec::<i32>::new()); // Not executed
619/// ```
620///
621/// ## With or_else Branch
622///
623/// ```rust
624/// use prism3_function::{MutatorOnce, BoxMutatorOnce};
625///
626/// let data1 = vec![1, 2, 3];
627/// let data2 = vec![99];
628/// let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
629///     x.extend(data1);
630/// })
631/// .when(|x: &Vec<i32>| !x.is_empty())
632/// .or_else(move |x: &mut Vec<i32>| {
633///     x.extend(data2);
634/// });
635///
636/// let mut target = vec![0];
637/// mutator.mutate(&mut target);
638/// assert_eq!(target, vec![0, 1, 2, 3]); // when branch executed
639///
640/// let data3 = vec![4, 5];
641/// let data4 = vec![99];
642/// let mutator2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
643///     x.extend(data3);
644/// })
645/// .when(|x: &Vec<i32>| x.is_empty())
646/// .or_else(move |x: &mut Vec<i32>| {
647///     x.extend(data4);
648/// });
649///
650/// let mut target2 = vec![0];
651/// mutator2.mutate(&mut target2);
652/// assert_eq!(target2, vec![0, 99]); // or_else branch executed
653/// ```
654///
655/// # Author
656///
657/// Haixing Hu
658pub struct BoxConditionalMutatorOnce<T> {
659    mutator: BoxMutatorOnce<T>,
660    predicate: BoxPredicate<T>,
661}
662
663impl<T> MutatorOnce<T> for BoxConditionalMutatorOnce<T>
664where
665    T: 'static,
666{
667    fn mutate(self, value: &mut T) {
668        if self.predicate.test(value) {
669            self.mutator.mutate(value);
670        }
671    }
672
673    fn into_box(self) -> BoxMutatorOnce<T> {
674        let pred = self.predicate;
675        let mutator = self.mutator;
676        BoxMutatorOnce::new(move |t| {
677            if pred.test(t) {
678                mutator.mutate(t);
679            }
680        })
681    }
682}
683
684impl<T> BoxConditionalMutatorOnce<T>
685where
686    T: 'static,
687{
688    /// Chains another mutator in sequence
689    ///
690    /// Combines the current conditional mutator with another mutator into a new
691    /// mutator. The current conditional mutator executes first, followed by the
692    /// next mutator.
693    ///
694    /// # Parameters
695    ///
696    /// * `next` - The next mutator to execute. **Note: This parameter is passed
697    ///   by value and will transfer ownership.** Since `BoxMutatorOnce` cannot
698    ///   be cloned, the parameter will be consumed. Can be:
699    ///   - A closure: `|x: &mut T|`
700    ///   - A `BoxMutatorOnce<T>`
701    ///   - Any type implementing `MutatorOnce<T>`
702    ///
703    /// # Returns
704    ///
705    /// Returns a new `BoxMutatorOnce<T>`
706    ///
707    /// # Examples
708    ///
709    /// ```rust
710    /// use prism3_function::{MutatorOnce, BoxMutatorOnce};
711    ///
712    /// let data1 = vec![1, 2];
713    /// let cond1 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
714    ///     x.extend(data1);
715    /// }).when(|x: &Vec<i32>| !x.is_empty());
716    ///
717    /// let data2 = vec![3, 4];
718    /// let cond2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
719    ///     x.extend(data2);
720    /// }).when(|x: &Vec<i32>| x.len() < 10);
721    ///
722    /// // Both cond1 and cond2 are moved and consumed
723    /// let chained = cond1.and_then(cond2);
724    ///
725    /// let mut target = vec![0];
726    /// chained.mutate(&mut target);
727    /// assert_eq!(target, vec![0, 1, 2, 3, 4]);
728    /// // cond1.mutate(&mut target); // Would not compile - moved
729    /// // cond2.mutate(&mut target); // Would not compile - moved
730    /// ```
731    pub fn and_then<C>(self, next: C) -> BoxMutatorOnce<T>
732    where
733        C: MutatorOnce<T> + 'static,
734    {
735        let first = self;
736        BoxMutatorOnce::new(move |t| {
737            first.mutate(t);
738            next.mutate(t);
739        })
740    }
741
742    /// Adds an else branch
743    ///
744    /// Executes the original mutator when the condition is satisfied, otherwise
745    /// executes else_mutator.
746    ///
747    /// # Parameters
748    ///
749    /// * `else_mutator` - The mutator for the else branch. **Note: This parameter
750    ///   is passed by value and will transfer ownership.** Since `BoxMutatorOnce`
751    ///   cannot be cloned, the parameter will be consumed. Can be:
752    ///   - A closure: `|x: &mut T|`
753    ///   - A `BoxMutatorOnce<T>`
754    ///   - Any type implementing `MutatorOnce<T>`
755    ///
756    /// # Returns
757    ///
758    /// Returns the composed `BoxMutatorOnce<T>`
759    ///
760    /// # Examples
761    ///
762    /// ## Using a closure (recommended)
763    ///
764    /// ```rust
765    /// use prism3_function::{MutatorOnce, BoxMutatorOnce};
766    ///
767    /// let data1 = vec![1, 2, 3];
768    /// let data2 = vec![99];
769    /// let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
770    ///     x.extend(data1);
771    /// })
772    /// .when(|x: &Vec<i32>| !x.is_empty())
773    /// .or_else(move |x: &mut Vec<i32>| {
774    ///     x.extend(data2);
775    /// });
776    ///
777    /// let mut target = vec![0];
778    /// mutator.mutate(&mut target);
779    /// assert_eq!(target, vec![0, 1, 2, 3]); // Condition satisfied, execute when branch
780    ///
781    /// let data3 = vec![4, 5];
782    /// let data4 = vec![99];
783    /// let mutator2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
784    ///     x.extend(data3);
785    /// })
786    /// .when(|x: &Vec<i32>| x.is_empty())
787    /// .or_else(move |x: &mut Vec<i32>| {
788    ///     x.extend(data4);
789    /// });
790    ///
791    /// let mut target2 = vec![0];
792    /// mutator2.mutate(&mut target2);
793    /// assert_eq!(target2, vec![0, 99]); // Condition not satisfied, execute or_else branch
794    /// ```
795    pub fn or_else<C>(self, else_mutator: C) -> BoxMutatorOnce<T>
796    where
797        C: MutatorOnce<T> + 'static,
798    {
799        let pred = self.predicate;
800        let then_mut = self.mutator;
801        BoxMutatorOnce::new(move |t| {
802            if pred.test(t) {
803                then_mut.mutate(t);
804            } else {
805                else_mutator.mutate(t);
806            }
807        })
808    }
809}
810
811// ============================================================================
812// 4. Implement MutatorOnce trait for closures
813// ============================================================================
814
815impl<T, F> MutatorOnce<T> for F
816where
817    F: FnOnce(&mut T),
818{
819    fn mutate(self, value: &mut T) {
820        self(value)
821    }
822
823    fn into_box(self) -> BoxMutatorOnce<T>
824    where
825        Self: Sized + 'static,
826        T: 'static,
827    {
828        BoxMutatorOnce::new(self)
829    }
830}
831
832// ============================================================================
833// 4. Provide extension methods for closures
834// ============================================================================
835
836/// Extension trait providing one-time mutator composition methods for closures
837///
838/// Provides `and_then` and other composition methods for all closures that
839/// implement `FnOnce(&mut T)`, enabling direct method chaining on closures
840/// without explicit wrapper types.
841///
842/// # Features
843///
844/// - **Natural Syntax**: Chain operations directly on closures
845/// - **Returns BoxMutatorOnce**: Composition results are `BoxMutatorOnce<T>`
846///   for continued chaining
847/// - **Zero Cost**: No overhead when composing closures
848/// - **Automatic Implementation**: All `FnOnce(&mut T)` closures get these
849///   methods automatically
850///
851/// # Examples
852///
853/// ```rust
854/// use prism3_function::{MutatorOnce, FnMutatorOnceOps};
855///
856/// let data1 = vec![1, 2];
857/// let data2 = vec![3, 4];
858///
859/// let chained = (move |x: &mut Vec<i32>| x.extend(data1))
860///     .and_then(move |x: &mut Vec<i32>| x.extend(data2));
861///
862/// let mut target = vec![0];
863/// chained.mutate(&mut target);
864/// assert_eq!(target, vec![0, 1, 2, 3, 4]);
865/// ```
866///
867/// # Author
868///
869/// Haixing Hu
870pub trait FnMutatorOnceOps<T>: FnOnce(&mut T) + Sized {
871    /// Chains another mutator in sequence
872    ///
873    /// Returns a new mutator that first executes the current operation, then
874    /// executes the next operation. Consumes the current closure and returns
875    /// `BoxMutatorOnce<T>`.
876    ///
877    /// # Parameters
878    ///
879    /// * `next` - The mutator to execute after the current operation. **Note: This
880    ///   parameter is passed by value and will transfer ownership.** Since
881    ///   `BoxMutatorOnce` cannot be cloned, the parameter will be consumed.
882    ///   Can be:
883    ///   - A closure: `|x: &mut T|`
884    ///   - A `BoxMutatorOnce<T>`
885    ///   - Any type implementing `MutatorOnce<T>`
886    ///
887    /// # Returns
888    ///
889    /// Returns the composed `BoxMutatorOnce<T>`
890    ///
891    /// # Examples
892    ///
893    /// ```rust
894    /// use prism3_function::{MutatorOnce, FnMutatorOnceOps};
895    ///
896    /// let data1 = vec![1, 2];
897    /// let data2 = vec![3, 4];
898    ///
899    /// // Both closures are moved and consumed
900    /// let chained = (move |x: &mut Vec<i32>| x.extend(data1))
901    ///     .and_then(move |x: &mut Vec<i32>| x.extend(data2));
902    ///
903    /// let mut target = vec![0];
904    /// chained.mutate(&mut target);
905    /// assert_eq!(target, vec![0, 1, 2, 3, 4]);
906    /// // The original closures are consumed and no longer usable
907    /// ```
908    fn and_then<C>(self, next: C) -> BoxMutatorOnce<T>
909    where
910        Self: 'static,
911        C: MutatorOnce<T> + 'static,
912        T: 'static,
913    {
914        BoxMutatorOnce::new(move |t| {
915            self(t);
916            next.mutate(t);
917        })
918    }
919}
920
921/// Implements FnMutatorOnceOps for all closure types
922impl<T, F> FnMutatorOnceOps<T> for F where F: FnOnce(&mut T) {}