qubit_function/functions/function.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026.
4 * Haixing Hu, Qubit Co. Ltd.
5 *
6 * All rights reserved.
7 *
8 ******************************************************************************/
9//! # Function Types
10//!
11//! Provides Rust implementations of function traits for computing output values
12//! from input references. Functions borrow input values (not consuming them)
13//! and produce output values.
14//!
15//! It is similar to the `Fn(&T) -> R` trait in the standard library.
16//!
17//! This module provides the `Function<T, R>` trait and three
18//! implementations:
19//!
20//! - [`BoxFunction`]: Single ownership, not cloneable
21//! - [`ArcFunction`]: Thread-safe shared ownership, cloneable
22//! - [`RcFunction`]: Single-threaded shared ownership, cloneable
23//!
24//! # Author
25//!
26//! Haixing Hu
27use std::rc::Rc;
28use std::sync::Arc;
29
30use crate::functions::{
31 function_once::BoxFunctionOnce,
32 macros::{
33 impl_box_conditional_function,
34 impl_box_function_methods,
35 impl_conditional_function_clone,
36 impl_conditional_function_debug_display,
37 impl_fn_ops_trait,
38 impl_function_clone,
39 impl_function_common_methods,
40 impl_function_constant_method,
41 impl_function_debug_display,
42 impl_function_identity_method,
43 impl_shared_conditional_function,
44 impl_shared_function_methods,
45 },
46};
47use crate::macros::{
48 impl_arc_conversions,
49 impl_box_conversions,
50 impl_closure_trait,
51 impl_rc_conversions,
52};
53use crate::predicates::predicate::{
54 ArcPredicate,
55 BoxPredicate,
56 Predicate,
57 RcPredicate,
58};
59
60// ============================================================================
61// Core Trait
62// ============================================================================
63
64/// Function trait - computes output from input reference
65///
66/// Defines the behavior of a function: computing a value of type `R`
67/// from a reference to type `T` without consuming the input. This is analogous to
68/// `Fn(&T) -> R` in Rust's standard library, similar to Java's `Function<T, R>`.
69///
70/// # Type Parameters
71///
72/// * `T` - The type of the input value (borrowed)
73/// * `R` - The type of the output value
74///
75/// # Author
76///
77/// Haixing Hu
78pub trait Function<T, R> {
79 /// Applies the function to the input reference to produce an output value
80 ///
81 /// # Parameters
82 ///
83 /// * `t` - Reference to the input value
84 ///
85 /// # Returns
86 ///
87 /// The computed output value
88 fn apply(&self, t: &T) -> R;
89
90 /// Converts to BoxFunction
91 ///
92 /// **⚠️ Consumes `self`**: The original function becomes
93 /// unavailable after calling this method.
94 ///
95 /// # Default Implementation
96 ///
97 /// The default implementation wraps `self` in a `Box` and creates a
98 /// `BoxFunction`. Types can override this method to provide more
99 /// efficient conversions.
100 ///
101 /// # Returns
102 ///
103 /// Returns `BoxFunction<T, R>`
104 fn into_box(self) -> BoxFunction<T, R>
105 where
106 Self: Sized + 'static,
107 {
108 BoxFunction::new(move |t| self.apply(t))
109 }
110
111 /// Converts to RcFunction
112 ///
113 /// **⚠️ Consumes `self`**: The original function becomes
114 /// unavailable after calling this method.
115 ///
116 /// # Default Implementation
117 ///
118 /// The default implementation wraps `self` in an `Rc` and creates an
119 /// `RcFunction`. Types can override this method to provide more
120 /// efficient conversions.
121 ///
122 /// # Returns
123 ///
124 /// Returns `RcFunction<T, R>`
125 fn into_rc(self) -> RcFunction<T, R>
126 where
127 Self: Sized + 'static,
128 {
129 RcFunction::new(move |t| self.apply(t))
130 }
131
132 /// Converts to ArcFunction
133 ///
134 /// **⚠️ Consumes `self`**: The original function becomes
135 /// unavailable after calling this method.
136 ///
137 /// # Default Implementation
138 ///
139 /// The default implementation wraps `self` in an `Arc` and creates
140 /// an `ArcFunction`. Types can override this method to provide
141 /// more efficient conversions.
142 ///
143 /// # Returns
144 ///
145 /// Returns `ArcFunction<T, R>`
146 fn into_arc(self) -> ArcFunction<T, R>
147 where
148 Self: Sized + Send + Sync + 'static,
149 {
150 ArcFunction::new(move |t| self.apply(t))
151 }
152
153 /// Converts function to a closure
154 ///
155 /// **⚠️ Consumes `self`**: The original function becomes
156 /// unavailable after calling this method.
157 ///
158 /// # Default Implementation
159 ///
160 /// The default implementation creates a closure that captures `self`
161 /// and calls its `transform` method. Types can override this method
162 /// to provide more efficient conversions.
163 ///
164 /// # Returns
165 ///
166 /// Returns a closure that implements `Fn(&T) -> R`
167 fn into_fn(self) -> impl Fn(&T) -> R
168 where
169 Self: Sized + 'static,
170 {
171 move |t| self.apply(t)
172 }
173
174 /// Converts to FunctionOnce
175 ///
176 /// **⚠️ Consumes `self`**: The original function becomes unavailable after calling this method.
177 ///
178 /// Converts a reusable function to a one-time function that consumes itself on use.
179 /// This enables passing `Function` to functions that require `FunctionOnce`.
180 ///
181 /// # Returns
182 ///
183 /// Returns a `BoxFunctionOnce<T, R>`
184 ///
185 /// # Examples
186 ///
187 /// ```rust
188 ///
189 /// fn takes_once<F: FunctionOnce<i32, i32>>(func: F, value: &i32) -> i32 {
190 /// func.apply(value)
191 /// }
192 ///
193 /// let func = BoxFunction::new(|x: &i32| x * 2);
194 /// let result = takes_once(func.into_once(), &5);
195 /// assert_eq!(result, 10);
196 /// ```
197 fn into_once(self) -> BoxFunctionOnce<T, R>
198 where
199 Self: Sized + 'static,
200 {
201 BoxFunctionOnce::new(move |t| self.apply(t))
202 }
203
204 /// Converts to BoxFunction without consuming self
205 ///
206 /// **📌 Borrows `&self`**: The original function remains usable
207 /// after calling this method.
208 ///
209 /// # Default Implementation
210 ///
211 /// The default implementation creates a new `BoxFunction` that
212 /// captures a reference-counted clone. Types implementing `Clone`
213 /// can override this method to provide more efficient conversions.
214 ///
215 /// # Returns
216 ///
217 /// Returns `BoxFunction<T, R>`
218 ///
219 /// # Examples
220 ///
221 /// ```rust
222 /// use qubit_function::{ArcFunction, Function};
223 ///
224 /// let double = ArcFunction::new(|x: i32| x * 2);
225 /// let boxed = double.to_box();
226 ///
227 /// // Original function still usable
228 /// assert_eq!(double.apply(21), 42);
229 /// assert_eq!(boxed.apply(21), 42);
230 /// ```
231 fn to_box(&self) -> BoxFunction<T, R>
232 where
233 Self: Clone + 'static,
234 {
235 self.clone().into_box()
236 }
237
238 /// Converts to RcFunction without consuming self
239 ///
240 /// **📌 Borrows `&self`**: The original function remains usable
241 /// after calling this method.
242 ///
243 /// # Default Implementation
244 ///
245 /// The default implementation creates a new `RcFunction` that
246 /// captures a reference-counted clone. Types implementing `Clone`
247 /// can override this method to provide more efficient conversions.
248 ///
249 /// # Returns
250 ///
251 /// Returns `RcFunction<T, R>`
252 ///
253 /// # Examples
254 ///
255 /// ```rust
256 /// use qubit_function::{ArcFunction, Function};
257 ///
258 /// let double = ArcFunction::new(|x: i32| x * 2);
259 /// let rc = double.to_rc();
260 ///
261 /// // Original function still usable
262 /// assert_eq!(double.apply(21), 42);
263 /// assert_eq!(rc.apply(21), 42);
264 /// ```
265 fn to_rc(&self) -> RcFunction<T, R>
266 where
267 Self: Clone + 'static,
268 {
269 self.clone().into_rc()
270 }
271
272 /// Converts to ArcFunction without consuming self
273 ///
274 /// **📌 Borrows `&self`**: The original function remains usable
275 /// after calling this method.
276 ///
277 /// # Default Implementation
278 ///
279 /// The default implementation creates a new `ArcFunction` that
280 /// captures a reference-counted clone. Types implementing `Clone`
281 /// can override this method to provide more efficient conversions.
282 ///
283 /// # Returns
284 ///
285 /// Returns `ArcFunction<T, R>`
286 ///
287 /// # Examples
288 ///
289 /// ```rust
290 /// use qubit_function::{ArcFunction, Function};
291 ///
292 /// let double = ArcFunction::new(|x: i32| x * 2);
293 /// let arc = double.to_arc();
294 ///
295 /// // Original function still usable
296 /// assert_eq!(double.apply(21), 42);
297 /// assert_eq!(arc.apply(21), 42);
298 /// ```
299 fn to_arc(&self) -> ArcFunction<T, R>
300 where
301 Self: Clone + Send + Sync + 'static,
302 {
303 self.clone().into_arc()
304 }
305
306 /// Converts function to a closure without consuming self
307 ///
308 /// **📌 Borrows `&self`**: The original function remains usable
309 /// after calling this method.
310 ///
311 /// # Default Implementation
312 ///
313 /// The default implementation creates a closure that captures a
314 /// clone of `self` and calls its `transform` method. Types can
315 /// override this method to provide more efficient conversions.
316 ///
317 /// # Returns
318 ///
319 /// Returns a closure that implements `Fn(&T) -> R`
320 ///
321 /// # Examples
322 ///
323 /// ```rust
324 /// use qubit_function::{ArcFunction, Function};
325 ///
326 /// let double = ArcFunction::new(|x: i32| x * 2);
327 /// let closure = double.to_fn();
328 ///
329 /// // Original function still usable
330 /// assert_eq!(double.apply(21), 42);
331 /// assert_eq!(closure(21), 42);
332 /// ```
333 fn to_fn(&self) -> impl Fn(&T) -> R
334 where
335 Self: Clone + 'static,
336 {
337 self.clone().into_fn()
338 }
339
340 /// Convert to FunctionOnce without consuming self
341 ///
342 /// **⚠️ Requires Clone**: This method requires `Self` to implement `Clone`.
343 /// Clones the current function and converts the clone to a one-time function.
344 ///
345 /// # Returns
346 ///
347 /// Returns a `BoxFunctionOnce<T, R>`
348 ///
349 /// # Examples
350 ///
351 /// ```rust
352 ///
353 /// fn takes_once<F: FunctionOnce<i32, i32>>(func: F, value: &i32) -> i32 {
354 /// func.apply(value)
355 /// }
356 ///
357 /// let func = BoxFunction::new(|x: &i32| x * 2);
358 /// let result = takes_once(func.to_once(), &5);
359 /// assert_eq!(result, 10);
360 /// ```
361 fn to_once(&self) -> BoxFunctionOnce<T, R>
362 where
363 Self: Clone + 'static,
364 {
365 self.clone().into_once()
366 }
367}
368
369// ============================================================================
370// BoxFunction - Box<dyn Fn(&T) -> R>
371// ============================================================================
372
373/// BoxFunction - function wrapper based on `Box<dyn Fn>`
374///
375/// A function wrapper that provides single ownership with reusable
376/// transformation. The function consumes the input and can be called
377/// multiple times.
378///
379/// # Features
380///
381/// - **Based on**: `Box<dyn Fn(&T) -> R>`
382/// - **Ownership**: Single ownership, cannot be cloned
383/// - **Reusability**: Can be called multiple times (each call consumes its
384/// input)
385/// - **Thread Safety**: Not thread-safe (no `Send + Sync` requirement)
386///
387/// # Author
388///
389/// Haixing Hu
390pub struct BoxFunction<T, R> {
391 function: Box<dyn Fn(&T) -> R>,
392 name: Option<String>,
393}
394
395impl<T, R> BoxFunction<T, R> {
396 // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
397 impl_function_common_methods!(
398 BoxFunction<T, R>,
399 (Fn(&T) -> R + 'static),
400 |f| Box::new(f)
401 );
402
403 // Generates: when(), and_then(), compose()
404 impl_box_function_methods!(
405 BoxFunction<T, R>,
406 BoxConditionalFunction,
407 Function
408 );
409}
410
411// Generates: constant() method for BoxFunction<T, R>
412impl_function_constant_method!(BoxFunction<T, R>, 'static);
413
414// Generates: identity() method for BoxFunction<T, T>
415impl_function_identity_method!(BoxFunction<T, T>);
416
417// Generates: Debug and Display implementations for BoxFunction<T, R>
418impl_function_debug_display!(BoxFunction<T, R>);
419
420// Implement Function trait for BoxFunction<T, R>
421impl<T, R> Function<T, R> for BoxFunction<T, R> {
422 fn apply(&self, t: &T) -> R {
423 (self.function)(t)
424 }
425
426 // Generates: into_box(), into_rc(), into_fn(), into_once()
427 impl_box_conversions!(
428 BoxFunction<T, R>,
429 RcFunction,
430 Fn(&T) -> R,
431 BoxFunctionOnce
432 );
433}
434
435// ============================================================================
436// RcFunction - Rc<dyn Fn(&T) -> R>
437// ============================================================================
438
439/// RcFunction - single-threaded function wrapper
440///
441/// A single-threaded, clonable function wrapper optimized for scenarios
442/// that require sharing without thread-safety overhead.
443///
444/// # Features
445///
446/// - **Based on**: `Rc<dyn Fn(&T) -> R>`
447/// - **Ownership**: Shared ownership via reference counting (non-atomic)
448/// - **Reusability**: Can be called multiple times (each call consumes its
449/// input)
450/// - **Thread Safety**: Not thread-safe (no `Send + Sync`)
451/// - **Clonable**: Cheap cloning via `Rc::clone`
452///
453/// # Author
454///
455/// Haixing Hu
456pub struct RcFunction<T, R> {
457 function: Rc<dyn Fn(&T) -> R>,
458 name: Option<String>,
459}
460
461impl<T, R> RcFunction<T, R> {
462 // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
463 impl_function_common_methods!(
464 RcFunction<T, R>,
465 (Fn(&T) -> R + 'static),
466 |f| Rc::new(f)
467 );
468
469 // Generates: when(), and_then(), compose()
470 impl_shared_function_methods!(
471 RcFunction<T, R>,
472 RcConditionalFunction,
473 into_rc,
474 Function,
475 'static
476 );
477}
478
479// Generates: constant() method for RcFunction<T, R>
480impl_function_constant_method!(RcFunction<T, R>, 'static);
481
482// Generates: identity() method for RcFunction<T, T>
483impl_function_identity_method!(RcFunction<T, T>);
484
485// Generates: Clone implementation for RcFunction<T, R>
486impl_function_clone!(RcFunction<T, R>);
487
488// Generates: Debug and Display implementations for RcFunction<T, R>
489impl_function_debug_display!(RcFunction<T, R>);
490
491// Implement Function trait for RcFunction<T, R>
492impl<T, R> Function<T, R> for RcFunction<T, R> {
493 fn apply(&self, t: &T) -> R {
494 (self.function)(t)
495 }
496
497 // Use macro to implement conversion methods
498 impl_rc_conversions!(
499 RcFunction<T, R>,
500 BoxFunction,
501 BoxFunctionOnce,
502 Fn(t: &T) -> R
503 );
504}
505
506// ============================================================================
507// ArcFunction - Arc<dyn Fn(&T) -> R + Send + Sync>
508// ============================================================================
509
510/// ArcFunction - thread-safe function wrapper
511///
512/// A thread-safe, clonable function wrapper suitable for multi-threaded
513/// scenarios. Can be called multiple times and shared across threads.
514///
515/// # Features
516///
517/// - **Based on**: `Arc<dyn Fn(&T) -> R + Send + Sync>`
518/// - **Ownership**: Shared ownership via reference counting
519/// - **Reusability**: Can be called multiple times (each call consumes its
520/// input)
521/// - **Thread Safety**: Thread-safe (`Send + Sync` required)
522/// - **Clonable**: Cheap cloning via `Arc::clone`
523///
524/// # Author
525///
526/// Haixing Hu
527pub struct ArcFunction<T, R> {
528 function: Arc<dyn Fn(&T) -> R + Send + Sync>,
529 name: Option<String>,
530}
531
532impl<T, R> ArcFunction<T, R> {
533 // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
534 impl_function_common_methods!(
535 ArcFunction<T, R>,
536 (Fn(&T) -> R + Send + Sync + 'static),
537 |f| Arc::new(f)
538 );
539
540 // Generates: when(), and_then(), compose()
541 impl_shared_function_methods!(
542 ArcFunction<T, R>,
543 ArcConditionalFunction,
544 into_arc,
545 Function,
546 Send + Sync + 'static
547 );
548}
549
550// Generates: constant() method for ArcFunction<T, R>
551impl_function_constant_method!(ArcFunction<T, R>, Send + Sync + 'static);
552
553// Generates: identity() method for ArcFunction<T, T>
554impl_function_identity_method!(ArcFunction<T, T>);
555
556// Generates: Clone implementation for ArcFunction<T, R>
557impl_function_clone!(ArcFunction<T, R>);
558
559// Generates: Debug and Display implementations for ArcFunction<T, R>
560impl_function_debug_display!(ArcFunction<T, R>);
561
562// Implement Function trait for ArcFunction<T, R>
563impl<T, R> Function<T, R> for ArcFunction<T, R> {
564 fn apply(&self, t: &T) -> R {
565 (self.function)(t)
566 }
567
568 // Use macro to implement conversion methods
569 impl_arc_conversions!(
570 ArcFunction<T, R>,
571 BoxFunction,
572 RcFunction,
573 BoxFunctionOnce,
574 Fn(t: &T) -> R
575 );
576}
577
578// ============================================================================
579// Blanket implementation for standard Fn trait
580// ============================================================================
581
582// Implement Function<T, R> for any type that implements Fn(&T) -> R
583impl_closure_trait!(
584 Function<T, R>,
585 apply,
586 BoxFunctionOnce,
587 Fn(input: &T) -> R
588);
589
590// ============================================================================
591// FnFunctionOps - Extension trait for closure functions
592// ============================================================================
593
594// Generates: FnFunctionOps trait and blanket implementation
595impl_fn_ops_trait!(
596 (Fn(&T) -> R),
597 FnFunctionOps,
598 BoxFunction,
599 Function,
600 BoxConditionalFunction
601);
602
603// ============================================================================
604// BoxConditionalFunction - Box-based Conditional Function
605// ============================================================================
606
607/// BoxConditionalFunction struct
608///
609/// A conditional function that only executes when a predicate is satisfied.
610/// Uses `BoxFunction` and `BoxPredicate` for single ownership semantics.
611///
612/// This type is typically created by calling `BoxFunction::when()` and is
613/// designed to work with the `or_else()` method to create if-then-else logic.
614///
615/// # Features
616///
617/// - **Single Ownership**: Not cloneable, consumes `self` on use
618/// - **Conditional Execution**: Only transforms when predicate returns `true`
619/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
620/// - **Implements Function**: Can be used anywhere a `Function` is expected
621///
622/// # Examples
623///
624/// ## With or_else Branch
625///
626/// ```rust
627/// use qubit_function::{Function, BoxFunction};
628///
629/// let double = BoxFunction::new(|x: i32| x * 2);
630/// let negate = BoxFunction::new(|x: i32| -x);
631/// let conditional = double.when(|x: &i32| *x > 0).or_else(negate);
632///
633/// assert_eq!(conditional.apply(5), 10); // when branch executed
634/// assert_eq!(conditional.apply(-5), 5); // or_else branch executed
635/// ```
636///
637/// # Author
638///
639/// Haixing Hu
640pub struct BoxConditionalFunction<T, R> {
641 function: BoxFunction<T, R>,
642 predicate: BoxPredicate<T>,
643}
644
645// Use macro to generate conditional function implementations
646impl_box_conditional_function!(
647 BoxConditionalFunction<T, R>,
648 BoxFunction,
649 Function
650);
651
652// Use macro to generate conditional function debug and display implementations
653impl_conditional_function_debug_display!(BoxConditionalFunction<T, R>);
654
655// ============================================================================
656// RcConditionalFunction - Rc-based Conditional Function
657// ============================================================================
658
659/// RcConditionalFunction struct
660///
661/// A single-threaded conditional function that only executes when a
662/// predicate is satisfied. Uses `RcFunction` and `RcPredicate` for shared
663/// ownership within a single thread.
664///
665/// This type is typically created by calling `RcFunction::when()` and is
666/// designed to work with the `or_else()` method to create if-then-else logic.
667///
668/// # Features
669///
670/// - **Shared Ownership**: Cloneable via `Rc`, multiple owners allowed
671/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
672/// - **Conditional Execution**: Only transforms when predicate returns `true`
673/// - **No Lock Overhead**: More efficient than `ArcConditionalFunction`
674///
675/// # Examples
676///
677/// ```rust
678/// use qubit_function::{Function, RcFunction};
679///
680/// let double = RcFunction::new(|x: i32| x * 2);
681/// let identity = RcFunction::<i32, i32>::identity();
682/// let conditional = double.when(|x: &i32| *x > 0).or_else(identity);
683///
684/// let conditional_clone = conditional.clone();
685///
686/// assert_eq!(conditional.apply(5), 10);
687/// assert_eq!(conditional_clone.apply(-5), -5);
688/// ```
689///
690/// # Author
691///
692/// Haixing Hu
693pub struct RcConditionalFunction<T, R> {
694 function: RcFunction<T, R>,
695 predicate: RcPredicate<T>,
696}
697
698// Use macro to generate conditional function implementations
699impl_shared_conditional_function!(
700 RcConditionalFunction<T, R>,
701 RcFunction,
702 Function,
703 'static
704);
705
706// Use macro to generate conditional function clone implementations
707impl_conditional_function_clone!(RcConditionalFunction<T, R>);
708
709// Use macro to generate conditional function debug and display implementations
710impl_conditional_function_debug_display!(RcConditionalFunction<T, R>);
711
712// ============================================================================
713// ArcConditionalFunction - Arc-based Conditional Function
714// ============================================================================
715
716/// ArcConditionalFunction struct
717///
718/// A thread-safe conditional function that only executes when a predicate is
719/// satisfied. Uses `ArcFunction` and `ArcPredicate` for shared ownership
720/// across threads.
721///
722/// This type is typically created by calling `ArcFunction::when()` and is
723/// designed to work with the `or_else()` method to create if-then-else logic.
724///
725/// # Features
726///
727/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
728/// - **Thread-Safe**: Implements `Send + Sync`, safe for concurrent use
729/// - **Conditional Execution**: Only transforms when predicate returns `true`
730/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
731///
732/// # Examples
733///
734/// ```rust
735/// use qubit_function::{Function, ArcFunction};
736///
737/// let double = ArcFunction::new(|x: i32| x * 2);
738/// let identity = ArcFunction::<i32, i32>::identity();
739/// let conditional = double.when(|x: &i32| *x > 0).or_else(identity);
740///
741/// let conditional_clone = conditional.clone();
742///
743/// assert_eq!(conditional.apply(5), 10);
744/// assert_eq!(conditional_clone.apply(-5), -5);
745/// ```
746///
747/// # Author
748///
749/// Haixing Hu
750pub struct ArcConditionalFunction<T, R> {
751 function: ArcFunction<T, R>,
752 predicate: ArcPredicate<T>,
753}
754
755// Use macro to generate conditional function implementations
756impl_shared_conditional_function!(
757 ArcConditionalFunction<T, R>,
758 ArcFunction,
759 Function,
760 Send + Sync + 'static
761);
762
763// Use macro to generate conditional function clone implementations
764impl_conditional_function_clone!(ArcConditionalFunction<T, R>);
765
766// Use macro to generate conditional function debug and display implementations
767impl_conditional_function_debug_display!(ArcConditionalFunction<T, R>);