prism3_function/
transformer_once.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025.
4 *    3-Prism Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # TransformerOnce Types
10//!
11//! Provides Rust implementations of consuming transformer traits similar to
12//! Rust's `FnOnce` trait, but with value-oriented semantics for functional
13//! programming patterns.
14//!
15//! This module provides the `TransformerOnce<T, R>` trait and one-time use
16//! implementations:
17//!
18//! - [`BoxTransformerOnce`]: Single ownership, one-time use
19//!
20//! # Author
21//!
22//! Hu Haixing
23
24use crate::predicate::{BoxPredicate, Predicate};
25
26// ============================================================================
27// Core Trait
28// ============================================================================
29
30/// TransformerOnce trait - consuming transformation that takes ownership
31///
32/// Defines the behavior of a consuming transformer: converting a value of
33/// type `T` to a value of type `R` by taking ownership of both self and the
34/// input. This trait is analogous to `FnOnce(T) -> R`.
35///
36/// # Type Parameters
37///
38/// * `T` - The type of the input value (consumed)
39/// * `R` - The type of the output value
40///
41/// # Author
42///
43/// Hu Haixing
44pub trait TransformerOnce<T, R> {
45    /// Transforms the input value, consuming both self and input
46    ///
47    /// # Parameters
48    ///
49    /// * `input` - The input value (consumed)
50    ///
51    /// # Returns
52    ///
53    /// The transformed output value
54    fn transform(self, input: T) -> R;
55
56    /// Converts to BoxTransformerOnce
57    ///
58    /// **⚠️ Consumes `self`**: The original transformer becomes unavailable
59    /// after calling this method.
60    ///
61    /// # Returns
62    ///
63    /// Returns `BoxTransformerOnce<T, R>`
64    fn into_box(self) -> BoxTransformerOnce<T, R>
65    where
66        Self: Sized + 'static,
67        T: 'static,
68        R: 'static;
69
70    /// Converts transformer to a closure
71    ///
72    /// **⚠️ Consumes `self`**: The original transformer becomes unavailable
73    /// after calling this method.
74    ///
75    /// # Returns
76    ///
77    /// Returns a closure that implements `FnOnce(T) -> R`
78    fn into_fn(self) -> impl FnOnce(T) -> R
79    where
80        Self: Sized + 'static,
81        T: 'static,
82        R: 'static;
83}
84
85// ============================================================================
86// BoxTransformerOnce - Box<dyn FnOnce(T) -> R>
87// ============================================================================
88
89/// BoxTransformerOnce - consuming transformer wrapper based on
90/// `Box<dyn FnOnce>`
91///
92/// A transformer wrapper that provides single ownership with one-time use
93/// semantics. Consumes both self and the input value.
94///
95/// # Features
96///
97/// - **Based on**: `Box<dyn FnOnce(T) -> R>`
98/// - **Ownership**: Single ownership, cannot be cloned
99/// - **Reusability**: Can only be called once (consumes self and input)
100/// - **Thread Safety**: Not thread-safe (no `Send + Sync` requirement)
101///
102/// # Author
103///
104/// Hu Haixing
105pub struct BoxTransformerOnce<T, R> {
106    function: Box<dyn FnOnce(T) -> R>,
107}
108
109impl<T, R> BoxTransformerOnce<T, R>
110where
111    T: 'static,
112    R: 'static,
113{
114    /// Creates a new BoxTransformerOnce
115    ///
116    /// # Parameters
117    ///
118    /// * `f` - The closure or function to wrap
119    ///
120    /// # Examples
121    ///
122    /// ```rust
123    /// use prism3_function::{BoxTransformerOnce, TransformerOnce};
124    ///
125    /// let parse = BoxTransformerOnce::new(|s: String| {
126    ///     s.parse::<i32>().unwrap_or(0)
127    /// });
128    ///
129    /// assert_eq!(parse.transform("42".to_string()), 42);
130    /// ```
131    pub fn new<F>(f: F) -> Self
132    where
133        F: FnOnce(T) -> R + 'static,
134    {
135        BoxTransformerOnce {
136            function: Box::new(f),
137        }
138    }
139
140    /// Creates an identity transformer
141    ///
142    /// # Examples
143    ///
144    /// ```rust
145    /// use prism3_function::{BoxTransformerOnce, TransformerOnce};
146    ///
147    /// let identity = BoxTransformerOnce::<i32, i32>::identity();
148    /// assert_eq!(identity.transform(42), 42);
149    /// ```
150    pub fn identity() -> BoxTransformerOnce<T, T> {
151        BoxTransformerOnce::new(|x| x)
152    }
153
154    /// Chain composition - applies self first, then after
155    ///
156    /// # Type Parameters
157    ///
158    /// * `S` - The output type of the after transformer
159    /// * `G` - The type of the after transformer (must implement
160    ///   TransformerOnce<R, S>)
161    ///
162    /// # Parameters
163    ///
164    /// * `after` - The transformer to apply after self. **Note: This parameter
165    ///   is passed by value and will transfer ownership.** Since
166    ///   `BoxTransformerOnce` cannot be cloned, the parameter will be consumed.
167    ///   Can be:
168    ///   - A closure: `|x: R| -> S`
169    ///   - A function pointer: `fn(R) -> S`
170    ///   - A `BoxTransformerOnce<R, S>`
171    ///   - Any type implementing `TransformerOnce<R, S>`
172    ///
173    /// # Returns
174    ///
175    /// A new BoxTransformerOnce representing the composition
176    ///
177    /// # Examples
178    ///
179    /// ```rust
180    /// use prism3_function::{BoxTransformerOnce, TransformerOnce};
181    ///
182    /// let add_one = BoxTransformerOnce::new(|x: i32| x + 1);
183    /// let double = BoxTransformerOnce::new(|x: i32| x * 2);
184    ///
185    /// // Both add_one and double are moved and consumed
186    /// let composed = add_one.and_then(double);
187    /// assert_eq!(composed.transform(5), 12); // (5 + 1) * 2
188    /// // add_one.transform(3); // Would not compile - moved
189    /// // double.transform(4);  // Would not compile - moved
190    /// ```
191    pub fn and_then<S, G>(self, after: G) -> BoxTransformerOnce<T, S>
192    where
193        S: 'static,
194        G: TransformerOnce<R, S> + 'static,
195    {
196        BoxTransformerOnce::new(move |x| {
197            let intermediate = (self.function)(x);
198            after.transform(intermediate)
199        })
200    }
201
202    /// Reverse composition - applies before first, then self
203    ///
204    /// # Type Parameters
205    ///
206    /// * `S` - The input type of the before transformer
207    /// * `G` - The type of the before transformer (must implement
208    ///   TransformerOnce<S, T>)
209    ///
210    /// # Parameters
211    ///
212    /// * `before` - The transformer to apply before self. **Note: This parameter
213    ///   is passed by value and will transfer ownership.** Since
214    ///   `BoxTransformerOnce` cannot be cloned, the parameter will be consumed.
215    ///   Can be:
216    ///   - A closure: `|x: S| -> T`
217    ///   - A function pointer: `fn(S) -> T`
218    ///   - A `BoxTransformerOnce<S, T>`
219    ///   - Any type implementing `TransformerOnce<S, T>`
220    ///
221    /// # Returns
222    ///
223    /// A new BoxTransformerOnce representing the composition
224    ///
225    /// # Examples
226    ///
227    /// ```rust
228    /// use prism3_function::{BoxTransformerOnce, TransformerOnce};
229    ///
230    /// let double = BoxTransformerOnce::new(|x: i32| x * 2);
231    /// let add_one = BoxTransformerOnce::new(|x: i32| x + 1);
232    ///
233    /// // Both double and add_one are moved and consumed
234    /// let composed = double.compose(add_one);
235    /// assert_eq!(composed.transform(5), 12); // (5 + 1) * 2
236    /// // double.transform(3); // Would not compile - moved
237    /// // add_one.transform(4); // Would not compile - moved
238    /// ```
239    pub fn compose<S, G>(self, before: G) -> BoxTransformerOnce<S, R>
240    where
241        S: 'static,
242        G: TransformerOnce<S, T> + 'static,
243    {
244        BoxTransformerOnce::new(move |x| {
245            let intermediate = before.transform(x);
246            (self.function)(intermediate)
247        })
248    }
249
250    /// Creates a conditional transformer
251    ///
252    /// Returns a transformer that only executes when a predicate is satisfied.
253    /// You must call `or_else()` to provide an alternative transformer.
254    ///
255    /// # Parameters
256    ///
257    /// * `predicate` - The condition to check. **Note: This parameter is passed
258    ///   by value and will transfer ownership.** If you need to preserve the
259    ///   original predicate, clone it first (if it implements `Clone`). Can be:
260    ///   - A closure: `|x: &T| -> bool`
261    ///   - A function pointer: `fn(&T) -> bool`
262    ///   - A `BoxPredicate<T>`
263    ///   - An `RcPredicate<T>`
264    ///   - An `ArcPredicate<T>`
265    ///   - Any type implementing `Predicate<T>`
266    ///
267    /// # Returns
268    ///
269    /// Returns `BoxConditionalTransformerOnce<T, R>`
270    ///
271    /// # Examples
272    ///
273    /// ## Basic usage with or_else
274    ///
275    /// ```rust
276    /// use prism3_function::{TransformerOnce, BoxTransformerOnce};
277    ///
278    /// let double = BoxTransformerOnce::new(|x: i32| x * 2);
279    /// let identity = BoxTransformerOnce::<i32, i32>::identity();
280    /// let conditional = double.when(|x: &i32| *x > 0).or_else(identity);
281    /// assert_eq!(conditional.transform(5), 10);
282    ///
283    /// let double2 = BoxTransformerOnce::new(|x: i32| x * 2);
284    /// let identity2 = BoxTransformerOnce::<i32, i32>::identity();
285    /// let conditional2 = double2.when(|x: &i32| *x > 0).or_else(identity2);
286    /// assert_eq!(conditional2.transform(-5), -5);
287    /// ```
288    ///
289    /// ## Preserving predicate with clone
290    ///
291    /// ```rust
292    /// use prism3_function::{TransformerOnce, BoxTransformerOnce, RcPredicate};
293    ///
294    /// let double = BoxTransformerOnce::new(|x: i32| x * 2);
295    /// let is_positive = RcPredicate::new(|x: &i32| *x > 0);
296    ///
297    /// // Clone to preserve original predicate
298    /// let conditional = double.when(is_positive.clone())
299    ///     .or_else(BoxTransformerOnce::identity());
300    ///
301    /// assert_eq!(conditional.transform(5), 10);
302    ///
303    /// // Original predicate still usable
304    /// assert!(is_positive.test(&3));
305    /// ```
306    pub fn when<P>(self, predicate: P) -> BoxConditionalTransformerOnce<T, R>
307    where
308        P: Predicate<T> + 'static,
309    {
310        BoxConditionalTransformerOnce {
311            transformer: self,
312            predicate: predicate.into_box(),
313        }
314    }
315}
316
317impl<T, R> BoxTransformerOnce<T, R>
318where
319    T: 'static,
320    R: Clone + 'static,
321{
322    /// Creates a constant transformer
323    ///
324    /// # Examples
325    ///
326    /// ```rust
327    /// use prism3_function::{BoxTransformerOnce, TransformerOnce};
328    ///
329    /// let constant = BoxTransformerOnce::constant("hello");
330    /// assert_eq!(constant.transform(123), "hello");
331    /// ```
332    pub fn constant(value: R) -> BoxTransformerOnce<T, R> {
333        BoxTransformerOnce::new(move |_| value.clone())
334    }
335}
336
337impl<T, R> TransformerOnce<T, R> for BoxTransformerOnce<T, R> {
338    fn transform(self, input: T) -> R {
339        (self.function)(input)
340    }
341
342    fn into_box(self) -> BoxTransformerOnce<T, R>
343    where
344        T: 'static,
345        R: 'static,
346    {
347        // Zero-cost: directly return itself
348        self
349    }
350
351    fn into_fn(self) -> impl FnOnce(T) -> R
352    where
353        T: 'static,
354        R: 'static,
355    {
356        move |t: T| self.transform(t)
357    }
358}
359
360// ============================================================================
361// BoxConditionalTransformerOnce - Box-based Conditional Transformer
362// ============================================================================
363
364/// BoxConditionalTransformerOnce struct
365///
366/// A conditional consuming transformer that only executes when a predicate is
367/// satisfied. Uses `BoxTransformerOnce` and `BoxPredicate` for single
368/// ownership semantics.
369///
370/// This type is typically created by calling `BoxTransformerOnce::when()` and
371/// is designed to work with the `or_else()` method to create if-then-else
372/// logic.
373///
374/// # Features
375///
376/// - **Single Ownership**: Not cloneable, consumes `self` on use
377/// - **One-time Use**: Can only be called once
378/// - **Conditional Execution**: Only transforms when predicate returns `true`
379/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
380///
381/// # Examples
382///
383/// ## With or_else Branch
384///
385/// ```rust
386/// use prism3_function::{TransformerOnce, BoxTransformerOnce};
387///
388/// let double = BoxTransformerOnce::new(|x: i32| x * 2);
389/// let negate = BoxTransformerOnce::new(|x: i32| -x);
390/// let conditional = double.when(|x: &i32| *x > 0).or_else(negate);
391/// assert_eq!(conditional.transform(5), 10); // when branch executed
392///
393/// let double2 = BoxTransformerOnce::new(|x: i32| x * 2);
394/// let negate2 = BoxTransformerOnce::new(|x: i32| -x);
395/// let conditional2 = double2.when(|x: &i32| *x > 0).or_else(negate2);
396/// assert_eq!(conditional2.transform(-5), 5); // or_else branch executed
397/// ```
398///
399/// # Author
400///
401/// Haixing Hu
402pub struct BoxConditionalTransformerOnce<T, R> {
403    transformer: BoxTransformerOnce<T, R>,
404    predicate: BoxPredicate<T>,
405}
406
407impl<T, R> BoxConditionalTransformerOnce<T, R>
408where
409    T: 'static,
410    R: 'static,
411{
412    /// Adds an else branch
413    ///
414    /// Executes the original transformer when the condition is satisfied,
415    /// otherwise executes else_transformer.
416    ///
417    /// # Parameters
418    ///
419    /// * `else_transformer` - The transformer for the else branch, can be:
420    ///   - Closure: `|x: T| -> R`
421    ///   - `BoxTransformerOnce<T, R>`
422    ///   - Any type implementing `TransformerOnce<T, R>`
423    ///
424    /// # Returns
425    ///
426    /// Returns the composed `BoxTransformerOnce<T, R>`
427    ///
428    /// # Examples
429    ///
430    /// ## Using a closure (recommended)
431    ///
432    /// ```rust
433    /// use prism3_function::{TransformerOnce, BoxTransformerOnce};
434    ///
435    /// let double = BoxTransformerOnce::new(|x: i32| x * 2);
436    /// let conditional = double.when(|x: &i32| *x > 0).or_else(|x: i32| -x);
437    /// assert_eq!(conditional.transform(5), 10); // Condition satisfied, execute double
438    ///
439    /// let double2 = BoxTransformerOnce::new(|x: i32| x * 2);
440    /// let conditional2 = double2.when(|x: &i32| *x > 0).or_else(|x: i32| -x);
441    /// assert_eq!(conditional2.transform(-5), 5); // Condition not satisfied, execute negate
442    /// ```
443    pub fn or_else<F>(self, else_transformer: F) -> BoxTransformerOnce<T, R>
444    where
445        F: TransformerOnce<T, R> + 'static,
446    {
447        let pred = self.predicate;
448        let then_trans = self.transformer;
449        BoxTransformerOnce::new(move |t| {
450            if pred.test(&t) {
451                then_trans.transform(t)
452            } else {
453                else_transformer.transform(t)
454            }
455        })
456    }
457}
458
459// ============================================================================
460// Blanket implementation for standard FnOnce trait
461// ============================================================================
462
463/// Implement TransformerOnce<T, R> for any type that implements
464/// FnOnce(T) -> R
465///
466/// This allows once-callable closures and function pointers to be used
467/// directly with our TransformerOnce trait without wrapping.
468///
469/// # Examples
470///
471/// ```rust
472/// use prism3_function::TransformerOnce;
473///
474/// fn parse(s: String) -> i32 {
475///     s.parse().unwrap_or(0)
476/// }
477///
478/// assert_eq!(parse.transform("42".to_string()), 42);
479///
480/// let owned_value = String::from("hello");
481/// let consume = |s: String| {
482///     format!("{} world", s)
483/// };
484/// assert_eq!(consume.transform(owned_value), "hello world");
485/// ```
486///
487/// # Author
488///
489/// Hu Haixing
490impl<F, T, R> TransformerOnce<T, R> for F
491where
492    F: FnOnce(T) -> R,
493    T: 'static,
494    R: 'static,
495{
496    fn transform(self, input: T) -> R {
497        self(input)
498    }
499
500    fn into_box(self) -> BoxTransformerOnce<T, R>
501    where
502        Self: Sized + 'static,
503    {
504        BoxTransformerOnce::new(self)
505    }
506
507    fn into_fn(self) -> impl FnOnce(T) -> R
508    where
509        Self: Sized + 'static,
510    {
511        move |input: T| -> R { self(input) }
512    }
513}
514
515// ============================================================================
516// FnTransformerOnceOps - Extension trait for FnOnce transformers
517// ============================================================================
518
519/// Extension trait for closures implementing `FnOnce(T) -> R`
520///
521/// Provides composition methods (`and_then`, `compose`, `when`) for one-time
522/// use closures and function pointers without requiring explicit wrapping in
523/// `BoxTransformerOnce`.
524///
525/// This trait is automatically implemented for all closures and function
526/// pointers that implement `FnOnce(T) -> R`.
527///
528/// # Design Rationale
529///
530/// While closures automatically implement `TransformerOnce<T, R>` through
531/// blanket implementation, they don't have access to instance methods like
532/// `and_then`, `compose`, and `when`. This extension trait provides those
533/// methods, returning `BoxTransformerOnce` for maximum flexibility.
534///
535/// # Examples
536///
537/// ## Chain composition with and_then
538///
539/// ```rust
540/// use prism3_function::{TransformerOnce, FnTransformerOnceOps};
541///
542/// let parse = |s: String| s.parse::<i32>().unwrap_or(0);
543/// let double = |x: i32| x * 2;
544///
545/// let composed = parse.and_then(double);
546/// assert_eq!(composed.transform("21".to_string()), 42);
547/// ```
548///
549/// ## Reverse composition with compose
550///
551/// ```rust
552/// use prism3_function::{TransformerOnce, FnTransformerOnceOps};
553///
554/// let double = |x: i32| x * 2;
555/// let to_string = |x: i32| x.to_string();
556///
557/// let composed = to_string.compose(double);
558/// assert_eq!(composed.transform(21), "42");
559/// ```
560///
561/// ## Conditional transformation with when
562///
563/// ```rust
564/// use prism3_function::{TransformerOnce, FnTransformerOnceOps};
565///
566/// let double = |x: i32| x * 2;
567/// let conditional = double.when(|x: &i32| *x > 0).or_else(|x: i32| -x);
568///
569/// assert_eq!(conditional.transform(5), 10);
570/// ```
571///
572/// # Author
573///
574/// Hu Haixing
575pub trait FnTransformerOnceOps<T, R>: FnOnce(T) -> R + Sized + 'static {
576    /// Chain composition - applies self first, then after
577    ///
578    /// Creates a new transformer that applies this transformer first, then
579    /// applies the after transformer to the result. Consumes self and returns
580    /// a `BoxTransformerOnce`.
581    ///
582    /// # Type Parameters
583    ///
584    /// * `S` - The output type of the after transformer
585    /// * `G` - The type of the after transformer (must implement
586    ///   TransformerOnce<R, S>)
587    ///
588    /// # Parameters
589    ///
590    /// * `after` - The transformer to apply after self. **Note: This parameter
591    ///   is passed by value and will transfer ownership.** Since this is a
592    ///   `FnOnce` transformer, the parameter will be consumed. Can be:
593    ///   - A closure: `|x: R| -> S`
594    ///   - A function pointer: `fn(R) -> S`
595    ///   - A `BoxTransformerOnce<R, S>`
596    ///   - Any type implementing `TransformerOnce<R, S>`
597    ///
598    /// # Returns
599    ///
600    /// A new `BoxTransformerOnce<T, S>` representing the composition
601    ///
602    /// # Examples
603    ///
604    /// ```rust
605    /// use prism3_function::{TransformerOnce, FnTransformerOnceOps,
606    ///     BoxTransformerOnce};
607    ///
608    /// let parse = |s: String| s.parse::<i32>().unwrap_or(0);
609    /// let double = BoxTransformerOnce::new(|x: i32| x * 2);
610    ///
611    /// // double is moved and consumed
612    /// let composed = parse.and_then(double);
613    /// assert_eq!(composed.transform("21".to_string()), 42);
614    /// // double.transform(5); // Would not compile - moved
615    /// ```
616    fn and_then<S, G>(self, after: G) -> BoxTransformerOnce<T, S>
617    where
618        S: 'static,
619        G: TransformerOnce<R, S> + 'static,
620        T: 'static,
621        R: 'static,
622    {
623        BoxTransformerOnce::new(move |x: T| {
624            let intermediate = self(x);
625            after.transform(intermediate)
626        })
627    }
628
629    /// Reverse composition - applies before first, then self
630    ///
631    /// Creates a new transformer that applies the before transformer first,
632    /// then applies this transformer to the result. Consumes self and returns
633    /// a `BoxTransformerOnce`.
634    ///
635    /// # Type Parameters
636    ///
637    /// * `S` - The input type of the before transformer
638    /// * `G` - The type of the before transformer (must implement
639    ///   TransformerOnce<S, T>)
640    ///
641    /// # Parameters
642    ///
643    /// * `before` - The transformer to apply before self. **Note: This parameter
644    ///   is passed by value and will transfer ownership.** Since this is a
645    ///   `FnOnce` transformer, the parameter will be consumed. Can be:
646    ///   - A closure: `|x: S| -> T`
647    ///   - A function pointer: `fn(S) -> T`
648    ///   - A `BoxTransformerOnce<S, T>`
649    ///   - Any type implementing `TransformerOnce<S, T>`
650    ///
651    /// # Returns
652    ///
653    /// A new `BoxTransformerOnce<S, R>` representing the composition
654    ///
655    /// # Examples
656    ///
657    /// ```rust
658    /// use prism3_function::{TransformerOnce, FnTransformerOnceOps,
659    ///     BoxTransformerOnce};
660    ///
661    /// let double = BoxTransformerOnce::new(|x: i32| x * 2);
662    /// let to_string = |x: i32| x.to_string();
663    ///
664    /// // double is moved and consumed
665    /// let composed = to_string.compose(double);
666    /// assert_eq!(composed.transform(21), "42");
667    /// // double.transform(5); // Would not compile - moved
668    /// ```
669    fn compose<S, G>(self, before: G) -> BoxTransformerOnce<S, R>
670    where
671        S: 'static,
672        G: TransformerOnce<S, T> + 'static,
673        T: 'static,
674        R: 'static,
675    {
676        BoxTransformerOnce::new(move |x: S| {
677            let intermediate = before.transform(x);
678            self(intermediate)
679        })
680    }
681
682    /// Creates a conditional transformer
683    ///
684    /// Returns a transformer that only executes when a predicate is satisfied.
685    /// You must call `or_else()` to provide an alternative transformer for when
686    /// the condition is not satisfied.
687    ///
688    /// # Parameters
689    ///
690    /// * `predicate` - The condition to check. **Note: This parameter is passed
691    ///   by value and will transfer ownership.** If you need to preserve the
692    ///   original predicate, clone it first (if it implements `Clone`). Can be:
693    ///   - A closure: `|x: &T| -> bool`
694    ///   - A function pointer: `fn(&T) -> bool`
695    ///   - A `BoxPredicate<T>`
696    ///   - An `RcPredicate<T>`
697    ///   - An `ArcPredicate<T>`
698    ///   - Any type implementing `Predicate<T>`
699    ///
700    /// # Returns
701    ///
702    /// Returns `BoxConditionalTransformerOnce<T, R>`
703    ///
704    /// # Examples
705    ///
706    /// ## Basic usage with or_else
707    ///
708    /// ```rust
709    /// use prism3_function::{TransformerOnce, FnTransformerOnceOps};
710    ///
711    /// let double = |x: i32| x * 2;
712    /// let conditional = double.when(|x: &i32| *x > 0).or_else(|x: i32| -x);
713    ///
714    /// assert_eq!(conditional.transform(5), 10);
715    /// ```
716    ///
717    /// ## Preserving predicate with clone
718    ///
719    /// ```rust
720    /// use prism3_function::{TransformerOnce, FnTransformerOnceOps,
721    ///     RcPredicate};
722    ///
723    /// let double = |x: i32| x * 2;
724    /// let is_positive = RcPredicate::new(|x: &i32| *x > 0);
725    ///
726    /// // Clone to preserve original predicate
727    /// let conditional = double.when(is_positive.clone())
728    ///     .or_else(|x: i32| -x);
729    ///
730    /// assert_eq!(conditional.transform(5), 10);
731    ///
732    /// // Original predicate still usable
733    /// assert!(is_positive.test(&3));
734    /// ```
735    fn when<P>(self, predicate: P) -> BoxConditionalTransformerOnce<T, R>
736    where
737        P: Predicate<T> + 'static,
738        T: 'static,
739        R: 'static,
740    {
741        BoxTransformerOnce::new(self).when(predicate)
742    }
743}
744
745/// Blanket implementation of FnTransformerOnceOps for all FnOnce closures
746///
747/// Automatically implements `FnTransformerOnceOps<T, R>` for any type that
748/// implements `FnOnce(T) -> R`.
749///
750/// # Author
751///
752/// Hu Haixing
753impl<T, R, F> FnTransformerOnceOps<T, R> for F where F: FnOnce(T) -> R + 'static {}
754
755// ============================================================================
756// UnaryOperatorOnce Trait - Marker trait for TransformerOnce<T, T>
757// ============================================================================
758
759/// UnaryOperatorOnce trait - marker trait for one-time use unary operators
760///
761/// A one-time use unary operator transforms a value of type `T` to another
762/// value of the same type `T`, consuming self in the process. This trait
763/// extends `TransformerOnce<T, T>` to provide semantic clarity for same-type
764/// transformations with consuming semantics. Equivalent to Java's
765/// `UnaryOperator<T>` but with FnOnce semantics.
766///
767/// # Automatic Implementation
768///
769/// This trait is automatically implemented for all types that implement
770/// `TransformerOnce<T, T>`, so you don't need to implement it manually.
771///
772/// # Type Parameters
773///
774/// * `T` - The type of both input and output values
775///
776/// # Examples
777///
778/// ## Using in generic constraints
779///
780/// ```rust
781/// use prism3_function::{UnaryOperatorOnce, TransformerOnce};
782///
783/// fn apply_once<T, O>(value: T, op: O) -> T
784/// where
785///     O: UnaryOperatorOnce<T>,
786/// {
787///     op.transform(value)
788/// }
789///
790/// let double = |x: i32| x * 2;
791/// assert_eq!(apply_once(21, double), 42);
792/// ```
793///
794/// # Author
795///
796/// Hu Haixing
797pub trait UnaryOperatorOnce<T>: TransformerOnce<T, T> {}
798
799/// Blanket implementation of UnaryOperatorOnce for all TransformerOnce<T, T>
800///
801/// This automatically implements `UnaryOperatorOnce<T>` for any type that
802/// implements `TransformerOnce<T, T>`.
803///
804/// # Author
805///
806/// Hu Haixing
807impl<F, T> UnaryOperatorOnce<T> for F
808where
809    F: TransformerOnce<T, T>,
810    T: 'static,
811{
812    // empty
813}
814
815// ============================================================================
816// Type Aliases for UnaryOperatorOnce (TransformerOnce<T, T>)
817// ============================================================================
818
819/// Type alias for `BoxTransformerOnce<T, T>`
820///
821/// Represents a one-time use unary operator that transforms a value of type `T`
822/// to another value of the same type `T`. Equivalent to Java's `UnaryOperator<T>`
823/// with consuming semantics (FnOnce).
824///
825/// # Examples
826///
827/// ```rust
828/// use prism3_function::{BoxUnaryOperatorOnce, TransformerOnce};
829///
830/// let increment: BoxUnaryOperatorOnce<i32> = BoxUnaryOperatorOnce::new(|x| x + 1);
831/// assert_eq!(increment.transform(41), 42);
832/// ```
833///
834/// # Author
835///
836/// Hu Haixing
837pub type BoxUnaryOperatorOnce<T> = BoxTransformerOnce<T, T>;