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_once(&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_once(&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, MutatorOnce};
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_once(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_once(&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_once();
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_once(&mut target);
232    /// assert_eq!(target, vec![0, 1, 2, 3]);
233    /// ```
234    fn mutate_once(self, value: &mut T);
235
236    /// Converts to `BoxMutatorOnce` (consuming)
237    ///
238    /// Consumes `self` and returns an owned `BoxMutatorOnce<T>`. The default
239    /// implementation simply wraps the consuming `mutate_once(self, &mut T)` call
240    /// in a `Box<dyn FnOnce(&mut T)>`. Types that can provide a cheaper or
241    /// identity conversion (for example `BoxMutatorOnce` itself) should
242    /// override this method.
243    ///
244    /// # Note
245    ///
246    /// - This method consumes the source value.
247    /// - Implementors may return `self` directly when `Self` is already a
248    ///   `BoxMutatorOnce<T>` to avoid the extra wrapper allocation.
249    fn into_box_once(self) -> BoxMutatorOnce<T>
250    where
251        Self: Sized + 'static,
252        T: 'static,
253    {
254        BoxMutatorOnce::new(move |t| self.mutate_once(t))
255    }
256
257    /// Converts to a consuming closure `FnOnce(&mut T)`
258    ///
259    /// Consumes `self` and returns a closure that, when invoked, calls
260    /// `mutate_once(self, &mut T)`. This is the default, straightforward
261    /// implementation; types that can produce a more direct function pointer
262    /// or avoid additional captures may override it.
263    fn into_fn_once(self) -> impl FnOnce(&mut T)
264    where
265        Self: Sized + 'static,
266        T: 'static,
267    {
268        move |t| self.mutate_once(t)
269    }
270
271    /// Non-consuming adapter to `BoxMutatorOnce`
272    ///
273    /// Creates a `BoxMutatorOnce<T>` that does not consume `self`. The default
274    /// implementation requires `Self: Clone` and clones the receiver for the
275    /// stored closure; the clone is consumed when the boxed mutator is invoked.
276    /// Types that can provide a zero-cost adapter (for example clonable
277    /// closures) should override this method to avoid unnecessary allocations.
278    fn to_box_once(&self) -> BoxMutatorOnce<T>
279    where
280        Self: Sized + Clone + 'static,
281        T: 'static,
282    {
283        self.clone().into_box_once()
284    }
285
286    /// Non-consuming adapter to a callable `FnOnce(&mut T)`
287    ///
288    /// Returns a closure that does not consume `self`. The default requires
289    /// `Self: Clone` and clones `self` for the captured closure; the clone is
290    /// consumed when the returned closure is invoked. Implementors may provide
291    /// more efficient adapters for specific types.
292    fn to_fn_once(&self) -> impl FnOnce(&mut T)
293    where
294        Self: Sized + Clone + 'static,
295        T: 'static,
296    {
297        self.clone().into_fn_once()
298    }
299}
300
301// ============================================================================
302// 2. BoxMutatorOnce - Single Ownership Implementation
303// ============================================================================
304
305/// BoxMutatorOnce struct
306///
307/// A one-time mutator implementation based on `Box<dyn FnOnce(&mut T)>` for
308/// single ownership scenarios. This is the only MutatorOnce implementation type
309/// because FnOnce conflicts with shared ownership semantics.
310///
311/// # Features
312///
313/// - **Single Ownership**: Not cloneable, consumes self on use
314/// - **Zero Overhead**: No reference counting or locking
315/// - **Move Semantics**: Can capture and move variables
316/// - **Method Chaining**: Compose multiple operations via `and_then`
317///
318/// # Use Cases
319///
320/// Choose `BoxMutatorOnce` when:
321/// - Need to store FnOnce closures (with moved captured variables)
322/// - One-time resource transfer operations
323/// - Post-initialization callbacks
324/// - Complex operations requiring ownership transfer
325///
326/// # Performance
327///
328/// `BoxMutatorOnce` performance characteristics:
329/// - No reference counting overhead
330/// - No lock acquisition or runtime borrow checking
331/// - Direct function call through vtable
332/// - Minimal memory footprint (single pointer)
333///
334/// # Why No Arc/Rc Variants?
335///
336/// FnOnce can only be called once, which conflicts with Arc/Rc shared ownership
337/// semantics:
338/// - Arc/Rc implies multiple owners might need to call
339/// - FnOnce is consumed after calling, cannot be called again
340/// - This semantic incompatibility makes Arc/Rc variants meaningless
341///
342/// # Examples
343///
344/// ## Basic Usage
345///
346/// ```rust
347/// use prism3_function::{MutatorOnce, BoxMutatorOnce};
348///
349/// let data = vec![1, 2, 3];
350/// let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
351///     x.extend(data); // Move data
352/// });
353///
354/// let mut target = vec![0];
355/// mutator.mutate_once(&mut target);
356/// assert_eq!(target, vec![0, 1, 2, 3]);
357/// ```
358///
359/// ## Method Chaining
360///
361/// ```rust
362/// use prism3_function::{MutatorOnce, BoxMutatorOnce};
363///
364/// let data1 = vec![1, 2];
365/// let data2 = vec![3, 4];
366///
367/// let chained = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
368///     x.extend(data1);
369/// })
370/// .and_then(move |x: &mut Vec<i32>| {
371///     x.extend(data2);
372/// });
373///
374/// let mut target = vec![0];
375/// chained.mutate_once(&mut target);
376/// assert_eq!(target, vec![0, 1, 2, 3, 4]);
377/// ```
378///
379/// # Author
380///
381/// Haixing Hu
382pub struct BoxMutatorOnce<T> {
383    function: Box<dyn FnOnce(&mut T)>,
384}
385
386impl<T> BoxMutatorOnce<T>
387where
388    T: 'static,
389{
390    /// Creates a new BoxMutatorOnce
391    ///
392    /// # Parameters
393    ///
394    /// * `f` - The closure to wrap
395    ///
396    /// # Returns
397    ///
398    /// Returns a new `BoxMutatorOnce<T>` instance
399    ///
400    /// # Examples
401    ///
402    /// ```rust
403    /// use prism3_function::{MutatorOnce, BoxMutatorOnce};
404    ///
405    /// let data = String::from("world");
406    /// let mutator = BoxMutatorOnce::new(move |x: &mut String| {
407    ///     x.push_str(" ");
408    ///     x.push_str(&data); // Move data
409    /// });
410    ///
411    /// let mut target = String::from("hello");
412    /// mutator.mutate_once(&mut target);
413    /// assert_eq!(target, "hello world");
414    /// ```
415    pub fn new<F>(f: F) -> Self
416    where
417        F: FnOnce(&mut T) + 'static,
418    {
419        BoxMutatorOnce {
420            function: Box::new(f),
421        }
422    }
423
424    /// Creates a no-op mutator
425    ///
426    /// Returns a mutator that performs no operation.
427    ///
428    /// # Returns
429    ///
430    /// Returns a no-op mutator
431    ///
432    /// # Examples
433    ///
434    /// ```rust
435    /// use prism3_function::{MutatorOnce, BoxMutatorOnce};
436    ///
437    /// let noop = BoxMutatorOnce::<i32>::noop();
438    /// let mut value = 42;
439    /// noop.mutate_once(&mut value);
440    /// assert_eq!(value, 42); // Value unchanged
441    /// ```
442    pub fn noop() -> Self {
443        BoxMutatorOnce::new(|_| {})
444    }
445
446    /// Chains another mutator in sequence
447    ///
448    /// Returns a new mutator that first executes the current operation, then
449    /// executes the next operation. Consumes self.
450    ///
451    /// # Parameters
452    ///
453    /// * `next` - The mutator to execute after the current operation. **Note:
454    ///   This parameter is passed by value and will transfer ownership.** Since
455    ///   `BoxMutatorOnce` cannot be cloned, the parameter will be consumed.
456    ///   Can be:
457    ///   - A closure: `|x: &mut T|`
458    ///   - A `BoxMutatorOnce<T>`
459    ///   - Any type implementing `MutatorOnce<T>`
460    ///
461    /// # Returns
462    ///
463    /// Returns a new composed `BoxMutatorOnce<T>`
464    ///
465    /// # Examples
466    ///
467    /// ```rust
468    /// use prism3_function::{MutatorOnce, BoxMutatorOnce};
469    ///
470    /// let data1 = vec![1, 2];
471    /// let data2 = vec![3, 4];
472    /// let data3 = vec![5, 6];
473    ///
474    /// let chained = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
475    ///     x.extend(data1);
476    /// })
477    /// .and_then(move |x: &mut Vec<i32>| {
478    ///     x.extend(data2);
479    /// })
480    /// .and_then(move |x: &mut Vec<i32>| {
481    ///     x.extend(data3);
482    /// });
483    ///
484    /// let mut target = vec![0];
485    /// chained.mutate_once(&mut target);
486    /// assert_eq!(target, vec![0, 1, 2, 3, 4, 5, 6]);
487    /// ```
488    pub fn and_then<C>(self, next: C) -> Self
489    where
490        C: MutatorOnce<T> + 'static,
491    {
492        let first = self.function;
493        BoxMutatorOnce::new(move |t| {
494            first(t);
495            next.mutate_once(t);
496        })
497    }
498
499    /// Creates a conditional mutator
500    ///
501    /// Returns a mutator that only executes when a predicate is satisfied.
502    ///
503    /// # Parameters
504    ///
505    /// * `predicate` - The condition to check. **Note: This parameter is passed
506    ///   by value and will transfer ownership.** If you need to preserve the
507    ///   original predicate, clone it first (if it implements `Clone`). Can be:
508    ///   - A closure: `|x: &T| -> bool`
509    ///   - A function pointer: `fn(&T) -> bool`
510    ///   - A `BoxPredicate<T>`
511    ///   - An `RcPredicate<T>`
512    ///   - An `ArcPredicate<T>`
513    ///   - Any type implementing `Predicate<T>`
514    ///
515    /// # Returns
516    ///
517    /// Returns `BoxConditionalMutatorOnce<T>`
518    ///
519    /// # Examples
520    ///
521    /// ## Using a closure
522    ///
523    /// ```rust
524    /// use prism3_function::{MutatorOnce, BoxMutatorOnce};
525    ///
526    /// let data = vec![1, 2, 3];
527    /// let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
528    ///     x.extend(data);
529    /// });
530    /// let conditional = mutator.when(|x: &Vec<i32>| !x.is_empty());
531    ///
532    /// let mut target = vec![0];
533    /// conditional.mutate_once(&mut target);
534    /// assert_eq!(target, vec![0, 1, 2, 3]);
535    ///
536    /// let mut empty = Vec::new();
537    /// let data2 = vec![4, 5];
538    /// let mutator2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
539    ///     x.extend(data2);
540    /// });
541    /// let conditional2 = mutator2.when(|x: &Vec<i32>| x.len() > 5);
542    /// conditional2.mutate_once(&mut empty);
543    /// assert_eq!(empty, Vec::<i32>::new()); // Unchanged
544    /// ```
545    ///
546    /// ## Preserving predicate with clone
547    ///
548    /// ```rust
549    /// use prism3_function::{MutatorOnce, BoxMutatorOnce, RcPredicate};
550    /// use prism3_function::predicate::Predicate;
551    ///
552    /// let data = vec![1, 2, 3];
553    /// let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
554    ///     x.extend(data);
555    /// });
556    /// let predicate = RcPredicate::new(|x: &Vec<i32>| !x.is_empty());
557    ///
558    /// // Clone to preserve original predicate
559    /// let conditional = mutator.when(predicate.clone());
560    ///
561    /// let mut target = vec![0];
562    /// conditional.mutate_once(&mut target);
563    /// assert_eq!(target, vec![0, 1, 2, 3]);
564    ///
565    /// // Original predicate still usable
566    /// assert!(predicate.test(&vec![1, 2]));
567    /// ```
568    ///
569    /// ## Using composed predicate
570    ///
571    /// ```rust
572    /// use prism3_function::{MutatorOnce, BoxMutatorOnce};
573    /// use prism3_function::predicate::{Predicate, FnPredicateOps};
574    ///
575    /// let pred = (|x: &Vec<i32>| !x.is_empty())
576    ///     .and(|x: &Vec<i32>| x.len() < 10);
577    /// let data = vec![1, 2, 3];
578    /// let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
579    ///     x.extend(data);
580    /// });
581    /// let conditional = mutator.when(pred);
582    ///
583    /// let mut target = vec![0];
584    /// conditional.mutate_once(&mut target);
585    /// assert_eq!(target, vec![0, 1, 2, 3]);
586    /// ```
587    pub fn when<P>(self, predicate: P) -> BoxConditionalMutatorOnce<T>
588    where
589        P: Predicate<T> + 'static,
590    {
591        BoxConditionalMutatorOnce {
592            mutator: self,
593            predicate: predicate.into_box(),
594        }
595    }
596}
597
598impl<T> MutatorOnce<T> for BoxMutatorOnce<T> {
599    fn mutate_once(self, value: &mut T) {
600        (self.function)(value)
601    }
602
603    fn into_box_once(self) -> BoxMutatorOnce<T>
604    where
605        T: 'static,
606    {
607        self
608    }
609
610    fn into_fn_once(self) -> impl FnOnce(&mut T)
611    where
612        T: 'static,
613    {
614        move |t| (self.function)(t)
615    }
616}
617
618// ============================================================================
619// 3. BoxConditionalMutatorOnce - Box-based Conditional Mutator
620// ============================================================================
621
622/// BoxConditionalMutatorOnce struct
623///
624/// A conditional one-time mutator that only executes when a predicate is satisfied.
625/// Uses `BoxMutatorOnce` and `BoxPredicate` for single ownership semantics.
626///
627/// This type is typically created by calling `BoxMutatorOnce::when()` and is
628/// designed to work with the `or_else()` method to create if-then-else logic.
629///
630/// # Features
631///
632/// - **Single Ownership**: Not cloneable, consumes `self` on use
633/// - **Conditional Execution**: Only mutates when predicate returns `true`
634/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
635/// - **Implements MutatorOnce**: Can be used anywhere a `MutatorOnce` is expected
636///
637/// # Examples
638///
639/// ## Basic Conditional Execution
640///
641/// ```rust
642/// use prism3_function::{MutatorOnce, BoxMutatorOnce};
643///
644/// let data = vec![1, 2, 3];
645/// let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
646///     x.extend(data);
647/// });
648/// let conditional = mutator.when(|x: &Vec<i32>| !x.is_empty());
649///
650/// let mut target = vec![0];
651/// conditional.mutate_once(&mut target);
652/// assert_eq!(target, vec![0, 1, 2, 3]); // Executed
653///
654/// let mut empty = Vec::new();
655/// let data2 = vec![4, 5];
656/// let mutator2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
657///     x.extend(data2);
658/// });
659/// let conditional2 = mutator2.when(|x: &Vec<i32>| x.len() > 5);
660/// conditional2.mutate_once(&mut empty);
661/// assert_eq!(empty, Vec::<i32>::new()); // Not executed
662/// ```
663///
664/// ## With or_else Branch
665///
666/// ```rust
667/// use prism3_function::{MutatorOnce, BoxMutatorOnce};
668///
669/// let data1 = vec![1, 2, 3];
670/// let data2 = vec![99];
671/// let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
672///     x.extend(data1);
673/// })
674/// .when(|x: &Vec<i32>| !x.is_empty())
675/// .or_else(move |x: &mut Vec<i32>| {
676///     x.extend(data2);
677/// });
678///
679/// let mut target = vec![0];
680/// mutator.mutate_once(&mut target);
681/// assert_eq!(target, vec![0, 1, 2, 3]); // when branch executed
682///
683/// let data3 = vec![4, 5];
684/// let data4 = vec![99];
685/// let mutator2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
686///     x.extend(data3);
687/// })
688/// .when(|x: &Vec<i32>| x.is_empty())
689/// .or_else(move |x: &mut Vec<i32>| {
690///     x.extend(data4);
691/// });
692///
693/// let mut target2 = vec![0];
694/// mutator2.mutate_once(&mut target2);
695/// assert_eq!(target2, vec![0, 99]); // or_else branch executed
696/// ```
697///
698/// # Author
699///
700/// Haixing Hu
701pub struct BoxConditionalMutatorOnce<T> {
702    mutator: BoxMutatorOnce<T>,
703    predicate: BoxPredicate<T>,
704}
705
706impl<T> MutatorOnce<T> for BoxConditionalMutatorOnce<T>
707where
708    T: 'static,
709{
710    fn mutate_once(self, value: &mut T) {
711        if self.predicate.test(value) {
712            self.mutator.mutate_once(value);
713        }
714    }
715
716    fn into_box_once(self) -> BoxMutatorOnce<T> {
717        let pred = self.predicate;
718        let mutator = self.mutator;
719        BoxMutatorOnce::new(move |t| {
720            if pred.test(t) {
721                mutator.mutate_once(t);
722            }
723        })
724    }
725
726    fn into_fn_once(self) -> impl FnOnce(&mut T) {
727        let pred = self.predicate;
728        let mutator = self.mutator;
729        move |t: &mut T| {
730            if pred.test(t) {
731                mutator.mutate_once(t);
732            }
733        }
734    }
735}
736
737impl<T> BoxConditionalMutatorOnce<T>
738where
739    T: 'static,
740{
741    /// Chains another mutator in sequence
742    ///
743    /// Combines the current conditional mutator with another mutator into a new
744    /// mutator. The current conditional mutator executes first, followed by the
745    /// next mutator.
746    ///
747    /// # Parameters
748    ///
749    /// * `next` - The next mutator to execute. **Note: This parameter is passed
750    ///   by value and will transfer ownership.** Since `BoxMutatorOnce` cannot
751    ///   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 a new `BoxMutatorOnce<T>`
759    ///
760    /// # Examples
761    ///
762    /// ```rust
763    /// use prism3_function::{MutatorOnce, BoxMutatorOnce};
764    ///
765    /// let data1 = vec![1, 2];
766    /// let cond1 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
767    ///     x.extend(data1);
768    /// }).when(|x: &Vec<i32>| !x.is_empty());
769    ///
770    /// let data2 = vec![3, 4];
771    /// let cond2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
772    ///     x.extend(data2);
773    /// }).when(|x: &Vec<i32>| x.len() < 10);
774    ///
775    /// // Both cond1 and cond2 are moved and consumed
776    /// let chained = cond1.and_then(cond2);
777    ///
778    /// let mut target = vec![0];
779    /// chained.mutate_once(&mut target);
780    /// assert_eq!(target, vec![0, 1, 2, 3, 4]);
781    /// // cond1.mutate_once(&mut target); // Would not compile - moved
782    /// // cond2.mutate_once(&mut target); // Would not compile - moved
783    /// ```
784    pub fn and_then<C>(self, next: C) -> BoxMutatorOnce<T>
785    where
786        C: MutatorOnce<T> + 'static,
787    {
788        let first = self;
789        BoxMutatorOnce::new(move |t| {
790            first.mutate_once(t);
791            next.mutate_once(t);
792        })
793    }
794
795    /// Adds an else branch
796    ///
797    /// Executes the original mutator when the condition is satisfied, otherwise
798    /// executes else_mutator.
799    ///
800    /// # Parameters
801    ///
802    /// * `else_mutator` - The mutator for the else branch. **Note: This parameter
803    ///   is passed by value and will transfer ownership.** Since `BoxMutatorOnce`
804    ///   cannot be cloned, the parameter will be consumed. Can be:
805    ///   - A closure: `|x: &mut T|`
806    ///   - A `BoxMutatorOnce<T>`
807    ///   - Any type implementing `MutatorOnce<T>`
808    ///
809    /// # Returns
810    ///
811    /// Returns the composed `BoxMutatorOnce<T>`
812    ///
813    /// # Examples
814    ///
815    /// ## Using a closure (recommended)
816    ///
817    /// ```rust
818    /// use prism3_function::{MutatorOnce, BoxMutatorOnce};
819    ///
820    /// let data1 = vec![1, 2, 3];
821    /// let data2 = vec![99];
822    /// let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
823    ///     x.extend(data1);
824    /// })
825    /// .when(|x: &Vec<i32>| !x.is_empty())
826    /// .or_else(move |x: &mut Vec<i32>| {
827    ///     x.extend(data2);
828    /// });
829    ///
830    /// let mut target = vec![0];
831    /// mutator.mutate_once(&mut target);
832    /// assert_eq!(target, vec![0, 1, 2, 3]); // Condition satisfied, execute when branch
833    ///
834    /// let data3 = vec![4, 5];
835    /// let data4 = vec![99];
836    /// let mutator2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
837    ///     x.extend(data3);
838    /// })
839    /// .when(|x: &Vec<i32>| x.is_empty())
840    /// .or_else(move |x: &mut Vec<i32>| {
841    ///     x.extend(data4);
842    /// });
843    ///
844    /// let mut target2 = vec![0];
845    /// mutator2.mutate_once(&mut target2);
846    /// assert_eq!(target2, vec![0, 99]); // Condition not satisfied, execute or_else branch
847    /// ```
848    pub fn or_else<C>(self, else_mutator: C) -> BoxMutatorOnce<T>
849    where
850        C: MutatorOnce<T> + 'static,
851    {
852        let pred = self.predicate;
853        let then_mut = self.mutator;
854        BoxMutatorOnce::new(move |t| {
855            if pred.test(t) {
856                then_mut.mutate_once(t);
857            } else {
858                else_mutator.mutate_once(t);
859            }
860        })
861    }
862}
863
864// ============================================================================
865// 4. Implement MutatorOnce trait for closures
866// ============================================================================
867
868impl<T, F> MutatorOnce<T> for F
869where
870    F: FnOnce(&mut T),
871{
872    fn mutate_once(self, value: &mut T) {
873        self(value)
874    }
875
876    fn into_box_once(self) -> BoxMutatorOnce<T>
877    where
878        Self: Sized + 'static,
879        T: 'static,
880    {
881        BoxMutatorOnce::new(self)
882    }
883
884    fn into_fn_once(self) -> impl FnOnce(&mut T)
885    where
886        Self: Sized + 'static,
887        T: 'static,
888    {
889        self
890    }
891
892    // Provide specialized non-consuming conversions for closures that
893    // implement `Clone`. Many simple closures are zero-sized and `Clone`,
894    // allowing non-consuming adapters to be cheaply produced.
895    fn to_box_once(&self) -> BoxMutatorOnce<T>
896    where
897        Self: Sized + Clone + 'static,
898        T: 'static,
899    {
900        let cloned = self.clone();
901        BoxMutatorOnce::new(move |t| cloned.mutate_once(t))
902    }
903
904    fn to_fn_once(&self) -> impl FnOnce(&mut T)
905    where
906        Self: Sized + Clone + 'static,
907        T: 'static,
908    {
909        self.clone()
910    }
911}
912
913// ============================================================================
914// 4. Provide extension methods for closures
915// ============================================================================
916
917/// Extension trait providing one-time mutator composition methods for closures
918///
919/// Provides `and_then` and other composition methods for all closures that
920/// implement `FnOnce(&mut T)`, enabling direct method chaining on closures
921/// without explicit wrapper types.
922///
923/// # Features
924///
925/// - **Natural Syntax**: Chain operations directly on closures
926/// - **Returns BoxMutatorOnce**: Composition results are `BoxMutatorOnce<T>`
927///   for continued chaining
928/// - **Zero Cost**: No overhead when composing closures
929/// - **Automatic Implementation**: All `FnOnce(&mut T)` closures get these
930///   methods automatically
931///
932/// # Examples
933///
934/// ```rust
935/// use prism3_function::{MutatorOnce, FnMutatorOnceOps};
936///
937/// let data1 = vec![1, 2];
938/// let data2 = vec![3, 4];
939///
940/// let chained = (move |x: &mut Vec<i32>| x.extend(data1))
941///     .and_then(move |x: &mut Vec<i32>| x.extend(data2));
942///
943/// let mut target = vec![0];
944/// chained.mutate_once(&mut target);
945/// assert_eq!(target, vec![0, 1, 2, 3, 4]);
946/// ```
947///
948/// # Author
949///
950/// Haixing Hu
951pub trait FnMutatorOnceOps<T>: FnOnce(&mut T) + Sized {
952    /// Chains another mutator in sequence
953    ///
954    /// Returns a new mutator that first executes the current operation, then
955    /// executes the next operation. Consumes the current closure and returns
956    /// `BoxMutatorOnce<T>`.
957    ///
958    /// # Parameters
959    ///
960    /// * `next` - The mutator to execute after the current operation. **Note: This
961    ///   parameter is passed by value and will transfer ownership.** Since
962    ///   `BoxMutatorOnce` cannot be cloned, the parameter will be consumed.
963    ///   Can be:
964    ///   - A closure: `|x: &mut T|`
965    ///   - A `BoxMutatorOnce<T>`
966    ///   - Any type implementing `MutatorOnce<T>`
967    ///
968    /// # Returns
969    ///
970    /// Returns the composed `BoxMutatorOnce<T>`
971    ///
972    /// # Examples
973    ///
974    /// ```rust
975    /// use prism3_function::{MutatorOnce, FnMutatorOnceOps};
976    ///
977    /// let data1 = vec![1, 2];
978    /// let data2 = vec![3, 4];
979    ///
980    /// // Both closures are moved and consumed
981    /// let chained = (move |x: &mut Vec<i32>| x.extend(data1))
982    ///     .and_then(move |x: &mut Vec<i32>| x.extend(data2));
983    ///
984    /// let mut target = vec![0];
985    /// chained.mutate_once(&mut target);
986    /// assert_eq!(target, vec![0, 1, 2, 3, 4]);
987    /// // The original closures are consumed and no longer usable
988    /// ```
989    fn and_then<C>(self, next: C) -> BoxMutatorOnce<T>
990    where
991        Self: 'static,
992        C: MutatorOnce<T> + 'static,
993        T: 'static,
994    {
995        BoxMutatorOnce::new(move |t| {
996            self(t);
997            next.mutate_once(t);
998        })
999    }
1000}
1001
1002/// Implements FnMutatorOnceOps for all closure types
1003impl<T, F> FnMutatorOnceOps<T> for F where F: FnOnce(&mut T) {}