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