Skip to main content

qubit_function/transformers/
transformer_once.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit 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//! Haixing Hu
23
24use crate::macros::{
25    impl_box_once_conversions,
26    impl_closure_once_trait,
27};
28use crate::predicates::predicate::{
29    BoxPredicate,
30    Predicate,
31};
32use crate::transformers::macros::{
33    impl_box_conditional_transformer,
34    impl_box_transformer_methods,
35    impl_conditional_transformer_debug_display,
36    impl_transformer_common_methods,
37    impl_transformer_constant_method,
38    impl_transformer_debug_display,
39};
40
41// ============================================================================
42// Core Trait
43// ============================================================================
44
45/// TransformerOnce trait - consuming transformation that takes ownership
46///
47/// Defines the behavior of a consuming transformer: converting a value of
48/// type `T` to a value of type `R` by taking ownership of both self and the
49/// input. This trait is analogous to `FnOnce(T) -> R`.
50///
51/// # Type Parameters
52///
53/// * `T` - The type of the input value (consumed)
54/// * `R` - The type of the output value
55///
56/// # Author
57///
58/// Haixing Hu
59pub trait TransformerOnce<T, R> {
60    /// Transforms the input value, consuming both self and input
61    ///
62    /// # Parameters
63    ///
64    /// * `input` - The input value (consumed)
65    ///
66    /// # Returns
67    ///
68    /// The transformed output value
69    fn apply(self, input: T) -> R;
70
71    /// Converts to BoxTransformerOnce
72    ///
73    /// **⚠️ Consumes `self`**: The original transformer becomes unavailable
74    /// after calling this method.
75    ///
76    /// # Returns
77    ///
78    /// Returns `BoxTransformerOnce<T, R>`
79    ///
80    /// # Examples
81    ///
82    /// ```rust
83    /// use qubit_function::TransformerOnce;
84    ///
85    /// let double = |x: i32| x * 2;
86    /// let boxed = double.into_box();
87    /// assert_eq!(boxed.apply(21), 42);
88    /// ```
89    fn into_box(self) -> BoxTransformerOnce<T, R>
90    where
91        Self: Sized + 'static,
92        T: 'static,
93        R: 'static,
94    {
95        BoxTransformerOnce::new(move |input: T| self.apply(input))
96    }
97
98    /// Converts transformer to a closure
99    ///
100    /// **⚠️ Consumes `self`**: The original transformer becomes unavailable
101    /// after calling this method.
102    ///
103    /// # Returns
104    ///
105    /// Returns a closure that implements `FnOnce(T) -> R`
106    ///
107    /// # Examples
108    ///
109    /// ```rust
110    /// use qubit_function::TransformerOnce;
111    ///
112    /// let double = |x: i32| x * 2;
113    /// let func = double.into_fn();
114    /// assert_eq!(func(21), 42);
115    /// ```
116    fn into_fn(self) -> impl FnOnce(T) -> R
117    where
118        Self: Sized + 'static,
119    {
120        move |input: T| self.apply(input)
121    }
122
123    /// Converts to BoxTransformerOnce without consuming self
124    ///
125    /// **📌 Borrows `&self`**: The original transformer remains usable
126    /// after calling this method.
127    ///
128    /// # Default Implementation
129    ///
130    /// The default implementation creates a new `BoxTransformerOnce` that
131    /// captures a clone. Types implementing `Clone` can override this method
132    /// to provide more efficient conversions.
133    ///
134    /// # Returns
135    ///
136    /// Returns `BoxTransformerOnce<T, R>`
137    ///
138    /// # Examples
139    ///
140    /// ```rust
141    /// use qubit_function::TransformerOnce;
142    ///
143    /// let double = |x: i32| x * 2;
144    /// let boxed = double.to_box();
145    /// assert_eq!(boxed.apply(21), 42);
146    /// ```
147    fn to_box(&self) -> BoxTransformerOnce<T, R>
148    where
149        Self: Clone + 'static,
150        T: 'static,
151        R: 'static,
152    {
153        self.clone().into_box()
154    }
155
156    /// Converts transformer to a closure without consuming self
157    ///
158    /// **📌 Borrows `&self`**: The original transformer remains usable
159    /// after calling this method.
160    ///
161    /// # Default Implementation
162    ///
163    /// The default implementation creates a closure that captures a
164    /// clone of `self` and calls its `transform` method. Types can
165    /// override this method to provide more efficient conversions.
166    ///
167    /// # Returns
168    ///
169    /// Returns a closure that implements `FnOnce(T) -> R`
170    ///
171    /// # Examples
172    ///
173    /// ```rust
174    /// use qubit_function::TransformerOnce;
175    ///
176    /// let double = |x: i32| x * 2;
177    /// let func = double.to_fn();
178    /// assert_eq!(func(21), 42);
179    /// ```
180    fn to_fn(&self) -> impl FnOnce(T) -> R
181    where
182        Self: Clone + 'static,
183    {
184        self.clone().into_fn()
185    }
186}
187
188// ============================================================================
189// BoxTransformerOnce - Box<dyn FnOnce(T) -> R>
190// ============================================================================
191
192/// BoxTransformerOnce - consuming transformer wrapper based on
193/// `Box<dyn FnOnce>`
194///
195/// A transformer wrapper that provides single ownership with one-time use
196/// semantics. Consumes both self and the input value.
197///
198/// # Features
199///
200/// - **Based on**: `Box<dyn FnOnce(T) -> R>`
201/// - **Ownership**: Single ownership, cannot be cloned
202/// - **Reusability**: Can only be called once (consumes self and input)
203/// - **Thread Safety**: Not thread-safe (no `Send + Sync` requirement)
204///
205/// # Author
206///
207/// Haixing Hu
208pub struct BoxTransformerOnce<T, R> {
209    function: Box<dyn FnOnce(T) -> R>,
210    name: Option<String>,
211}
212
213// Implement BoxTransformerOnce
214impl<T, R> BoxTransformerOnce<T, R> {
215    impl_transformer_common_methods!(
216        BoxTransformerOnce<T, R>,
217        (FnOnce(T) -> R + 'static),
218        |f| Box::new(f)
219    );
220
221    impl_box_transformer_methods!(
222        BoxTransformerOnce<T, R>,
223        BoxConditionalTransformerOnce,
224        TransformerOnce
225    );
226}
227
228// Implement TransformerOnce trait for BoxTransformerOnce
229impl<T, R> TransformerOnce<T, R> for BoxTransformerOnce<T, R> {
230    fn apply(self, input: T) -> R {
231        (self.function)(input)
232    }
233
234    impl_box_once_conversions!(
235        BoxTransformerOnce<T, R>,
236        TransformerOnce,
237        FnOnce(T) -> R
238    );
239}
240
241// Implement constant method for BoxTransformerOnce
242impl_transformer_constant_method!(BoxTransformerOnce<T, R>);
243
244// Use macro to generate Debug and Display implementations
245impl_transformer_debug_display!(BoxTransformerOnce<T, R>);
246
247// ============================================================================
248// Blanket implementation for standard FnOnce trait
249// ============================================================================
250
251// Implement TransformerOnce for all FnOnce(T) -> R using macro
252impl_closure_once_trait!(
253    TransformerOnce<T, R>,
254    apply,
255    BoxTransformerOnce,
256    FnOnce(input: T) -> R
257);
258
259// ============================================================================
260// FnTransformerOnceOps - Extension trait for FnOnce transformers
261// ============================================================================
262
263/// Extension trait for closures implementing `FnOnce(T) -> R`
264///
265/// Provides composition methods (`and_then`, `compose`, `when`) for one-time
266/// use closures and function pointers without requiring explicit wrapping in
267/// `BoxTransformerOnce`.
268///
269/// This trait is automatically implemented for all closures and function
270/// pointers that implement `FnOnce(T) -> R`.
271///
272/// # Design Rationale
273///
274/// While closures automatically implement `TransformerOnce<T, R>` through
275/// blanket implementation, they don't have access to instance methods like
276/// `and_then`, `compose`, and `when`. This extension trait provides those
277/// methods, returning `BoxTransformerOnce` for maximum flexibility.
278///
279/// # Examples
280///
281/// ## Chain composition with and_then
282///
283/// ```rust
284/// use qubit_function::{TransformerOnce, FnTransformerOnceOps};
285///
286/// let parse = |s: String| s.parse::<i32>().unwrap_or(0);
287/// let double = |x: i32| x * 2;
288///
289/// let composed = parse.and_then(double);
290/// assert_eq!(composed.apply("21".to_string()), 42);
291/// ```
292///
293/// ## Reverse composition with compose
294///
295/// ```rust
296/// use qubit_function::{TransformerOnce, FnTransformerOnceOps};
297///
298/// let double = |x: i32| x * 2;
299/// let to_string = |x: i32| x.to_string();
300///
301/// let composed = to_string.compose(double);
302/// assert_eq!(composed.apply(21), "42");
303/// ```
304///
305/// ## Conditional transformation with when
306///
307/// ```rust
308/// use qubit_function::{TransformerOnce, FnTransformerOnceOps};
309///
310/// let double = |x: i32| x * 2;
311/// let conditional = double.when(|x: &i32| *x > 0).or_else(|x: i32| -x);
312///
313/// assert_eq!(conditional.apply(5), 10);
314/// ```
315///
316/// # Author
317///
318/// Haixing Hu
319pub trait FnTransformerOnceOps<T, R>: FnOnce(T) -> R + Sized {
320    /// Chain composition - applies self first, then after
321    ///
322    /// Creates a new transformer that applies this transformer first, then
323    /// applies the after transformer to the result. Consumes self and returns
324    /// a `BoxTransformerOnce`.
325    ///
326    /// # Type Parameters
327    ///
328    /// * `S` - The output type of the after transformer
329    /// * `G` - The type of the after transformer (must implement
330    ///   TransformerOnce<R, S>)
331    ///
332    /// # Parameters
333    ///
334    /// * `after` - The transformer to apply after self. **Note: This parameter
335    ///   is passed by value and will transfer ownership.** Since this is a
336    ///   `FnOnce` transformer, the parameter will be consumed. Can be:
337    ///   - A closure: `|x: R| -> S`
338    ///   - A function pointer: `fn(R) -> S`
339    ///   - A `BoxTransformerOnce<R, S>`
340    ///   - Any type implementing `TransformerOnce<R, S>`
341    ///
342    /// # Returns
343    ///
344    /// A new `BoxTransformerOnce<T, S>` representing the composition
345    ///
346    /// # Examples
347    ///
348    /// ```rust
349    /// use qubit_function::{TransformerOnce, FnTransformerOnceOps,
350    ///     BoxTransformerOnce};
351    ///
352    /// let parse = |s: String| s.parse::<i32>().unwrap_or(0);
353    /// let double = BoxTransformerOnce::new(|x: i32| x * 2);
354    ///
355    /// // double is moved and consumed
356    /// let composed = parse.and_then(double);
357    /// assert_eq!(composed.apply("21".to_string()), 42);
358    /// // double.apply(5); // Would not compile - moved
359    /// ```
360    fn and_then<S, G>(self, after: G) -> BoxTransformerOnce<T, S>
361    where
362        Self: 'static,
363        S: 'static,
364        G: TransformerOnce<R, S> + 'static,
365        T: 'static,
366        R: 'static,
367    {
368        BoxTransformerOnce::new(move |x: T| {
369            let intermediate = self(x);
370            after.apply(intermediate)
371        })
372    }
373
374    /// Creates a conditional transformer
375    ///
376    /// Returns a transformer that only executes when a predicate is satisfied.
377    /// You must call `or_else()` to provide an alternative transformer for when
378    /// the condition is not satisfied.
379    ///
380    /// # Parameters
381    ///
382    /// * `predicate` - The condition to check. **Note: This parameter is passed
383    ///   by value and will transfer ownership.** If you need to preserve the
384    ///   original predicate, clone it first (if it implements `Clone`). Can be:
385    ///   - A closure: `|x: &T| -> bool`
386    ///   - A function pointer: `fn(&T) -> bool`
387    ///   - A `BoxPredicate<T>`
388    ///   - An `RcPredicate<T>`
389    ///   - An `ArcPredicate<T>`
390    ///   - Any type implementing `Predicate<T>`
391    ///
392    /// # Returns
393    ///
394    /// Returns `BoxConditionalTransformerOnce<T, R>`
395    ///
396    /// # Examples
397    ///
398    /// ## Basic usage with or_else
399    ///
400    /// ```rust
401    /// use qubit_function::{TransformerOnce, FnTransformerOnceOps};
402    ///
403    /// let double = |x: i32| x * 2;
404    /// let conditional = double.when(|x: &i32| *x > 0).or_else(|x: i32| -x);
405    ///
406    /// assert_eq!(conditional.apply(5), 10);
407    /// ```
408    ///
409    /// ## Preserving predicate with clone
410    ///
411    /// ```rust
412    /// use qubit_function::{TransformerOnce, FnTransformerOnceOps,
413    ///     RcPredicate};
414    ///
415    /// let double = |x: i32| x * 2;
416    /// let is_positive = RcPredicate::new(|x: &i32| *x > 0);
417    ///
418    /// // Clone to preserve original predicate
419    /// let conditional = double.when(is_positive.clone())
420    ///     .or_else(|x: i32| -x);
421    ///
422    /// assert_eq!(conditional.apply(5), 10);
423    ///
424    /// // Original predicate still usable
425    /// assert!(is_positive.test(&3));
426    /// ```
427    fn when<P>(self, predicate: P) -> BoxConditionalTransformerOnce<T, R>
428    where
429        Self: 'static,
430        P: Predicate<T> + 'static,
431        T: 'static,
432        R: 'static,
433    {
434        BoxTransformerOnce::new(self).when(predicate)
435    }
436}
437
438/// Blanket implementation of FnTransformerOnceOps for all FnOnce closures
439///
440/// Automatically implements `FnTransformerOnceOps<T, R>` for any type that
441/// implements `FnOnce(T) -> R`.
442///
443/// # Author
444///
445/// Haixing Hu
446impl<T, R, F> FnTransformerOnceOps<T, R> for F where F: FnOnce(T) -> R {}
447
448// ============================================================================
449// UnaryOperatorOnce Trait - Marker trait for TransformerOnce<T, T>
450// ============================================================================
451
452/// UnaryOperatorOnce trait - marker trait for one-time use unary operators
453///
454/// A one-time use unary operator transforms a value of type `T` to another
455/// value of the same type `T`, consuming self in the process. This trait
456/// extends `TransformerOnce<T, T>` to provide semantic clarity for same-type
457/// transformations with consuming semantics. Equivalent to Java's
458/// `UnaryOperator<T>` but with FnOnce semantics.
459///
460/// # Automatic Implementation
461///
462/// This trait is automatically implemented for all types that implement
463/// `TransformerOnce<T, T>`, so you don't need to implement it manually.
464///
465/// # Type Parameters
466///
467/// * `T` - The type of both input and output values
468///
469/// # Examples
470///
471/// ## Using in generic constraints
472///
473/// ```rust
474/// use qubit_function::{UnaryOperatorOnce, TransformerOnce};
475///
476/// fn apply<T, O>(value: T, op: O) -> T
477/// where
478///     O: UnaryOperatorOnce<T>,
479/// {
480///     op.apply(value)
481/// }
482///
483/// let double = |x: i32| x * 2;
484/// assert_eq!(apply(21, double), 42);
485/// ```
486///
487/// # Author
488///
489/// Haixing Hu
490pub trait UnaryOperatorOnce<T>: TransformerOnce<T, T> {}
491
492/// Blanket implementation of UnaryOperatorOnce for all TransformerOnce<T, T>
493///
494/// This automatically implements `UnaryOperatorOnce<T>` for any type that
495/// implements `TransformerOnce<T, T>`.
496///
497/// # Author
498///
499/// Haixing Hu
500impl<F, T> UnaryOperatorOnce<T> for F
501where
502    F: TransformerOnce<T, T>,
503{
504    // empty
505}
506
507// ============================================================================
508// Type Aliases for UnaryOperatorOnce (TransformerOnce<T, T>)
509// ============================================================================
510
511/// Type alias for `BoxTransformerOnce<T, T>`
512///
513/// Represents a one-time use unary operator that transforms a value of type `T`
514/// to another value of the same type `T`. Equivalent to Java's `UnaryOperator<T>`
515/// with consuming semantics (FnOnce).
516///
517/// # Examples
518///
519/// ```rust
520/// use qubit_function::{BoxUnaryOperatorOnce, TransformerOnce};
521///
522/// let increment: BoxUnaryOperatorOnce<i32> = BoxUnaryOperatorOnce::new(|x| x + 1);
523/// assert_eq!(increment.apply(41), 42);
524/// ```
525///
526/// # Author
527///
528/// Haixing Hu
529pub type BoxUnaryOperatorOnce<T> = BoxTransformerOnce<T, T>;
530
531// ============================================================================
532// BoxConditionalTransformerOnce - Box-based Conditional Transformer
533// ============================================================================
534
535/// BoxConditionalTransformerOnce struct
536///
537/// A conditional consuming transformer that only executes when a predicate is
538/// satisfied. Uses `BoxTransformerOnce` and `BoxPredicate` for single
539/// ownership semantics.
540///
541/// This type is typically created by calling `BoxTransformerOnce::when()` and
542/// is designed to work with the `or_else()` method to create if-then-else
543/// logic.
544///
545/// # Features
546///
547/// - **Single Ownership**: Not cloneable, consumes `self` on use
548/// - **One-time Use**: Can only be called once
549/// - **Conditional Execution**: Only transforms when predicate returns `true`
550/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
551///
552/// # Examples
553///
554/// ## With or_else Branch
555///
556/// ```rust
557/// use qubit_function::{TransformerOnce, BoxTransformerOnce};
558///
559/// let double = BoxTransformerOnce::new(|x: i32| x * 2);
560/// let negate = BoxTransformerOnce::new(|x: i32| -x);
561/// let conditional = double.when(|x: &i32| *x > 0).or_else(negate);
562/// assert_eq!(conditional.apply(5), 10); // when branch executed
563///
564/// let double2 = BoxTransformerOnce::new(|x: i32| x * 2);
565/// let negate2 = BoxTransformerOnce::new(|x: i32| -x);
566/// let conditional2 = double2.when(|x: &i32| *x > 0).or_else(negate2);
567/// assert_eq!(conditional2.apply(-5), 5); // or_else branch executed
568/// ```
569///
570/// # Author
571///
572/// Haixing Hu
573pub struct BoxConditionalTransformerOnce<T, R> {
574    transformer: BoxTransformerOnce<T, R>,
575    predicate: BoxPredicate<T>,
576}
577
578// Implement BoxConditionalTransformerOnce
579impl_box_conditional_transformer!(
580    BoxConditionalTransformerOnce<T, R>,
581    BoxTransformerOnce,
582    TransformerOnce
583);
584
585// Use macro to generate Debug and Display implementations
586impl_conditional_transformer_debug_display!(BoxConditionalTransformerOnce<T, R>);