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) {}