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 /// use qubit_function::{BoxFunction, Function, FunctionOnce};
189 ///
190 /// fn takes_once<F: FunctionOnce<i32, i32>>(func: F, value: &i32) -> i32 {
191 /// func.apply(value)
192 /// }
193 ///
194 /// let func = BoxFunction::new(|x: &i32| x * 2);
195 /// let result = takes_once(func.into_once(), &5);
196 /// assert_eq!(result, 10);
197 /// ```
198 fn into_once(self) -> BoxFunctionOnce<T, R>
199 where
200 Self: Sized + 'static,
201 {
202 BoxFunctionOnce::new(move |t| self.apply(t))
203 }
204
205 /// Converts to BoxFunction without consuming self
206 ///
207 /// **📌 Borrows `&self`**: The original function remains usable
208 /// after calling this method.
209 ///
210 /// # Default Implementation
211 ///
212 /// The default implementation creates a new `BoxFunction` that
213 /// captures a reference-counted clone. Types implementing `Clone`
214 /// can override this method to provide more efficient conversions.
215 ///
216 /// # Returns
217 ///
218 /// Returns `BoxFunction<T, R>`
219 ///
220 /// # Examples
221 ///
222 /// ```rust
223 /// use qubit_function::{ArcFunction, Function};
224 ///
225 /// let double = ArcFunction::new(|x: &i32| x * 2);
226 /// let boxed = double.to_box();
227 ///
228 /// // Original function still usable
229 /// assert_eq!(double.apply(&21), 42);
230 /// assert_eq!(boxed.apply(&21), 42);
231 /// ```
232 fn to_box(&self) -> BoxFunction<T, R>
233 where
234 Self: Clone + 'static,
235 {
236 self.clone().into_box()
237 }
238
239 /// Converts to RcFunction without consuming self
240 ///
241 /// **📌 Borrows `&self`**: The original function remains usable
242 /// after calling this method.
243 ///
244 /// # Default Implementation
245 ///
246 /// The default implementation creates a new `RcFunction` that
247 /// captures a reference-counted clone. Types implementing `Clone`
248 /// can override this method to provide more efficient conversions.
249 ///
250 /// # Returns
251 ///
252 /// Returns `RcFunction<T, R>`
253 ///
254 /// # Examples
255 ///
256 /// ```rust
257 /// use qubit_function::{RcFunction, Function};
258 ///
259 /// let double = RcFunction::new(|x: &i32| x * 2);
260 /// let rc = double.to_rc();
261 ///
262 /// // Original function still usable
263 /// assert_eq!(double.apply(&21), 42);
264 /// assert_eq!(rc.apply(&21), 42);
265 /// ```
266 fn to_rc(&self) -> RcFunction<T, R>
267 where
268 Self: Clone + 'static,
269 {
270 self.clone().into_rc()
271 }
272
273 /// Converts to ArcFunction without consuming self
274 ///
275 /// **📌 Borrows `&self`**: The original function remains usable
276 /// after calling this method.
277 ///
278 /// # Default Implementation
279 ///
280 /// The default implementation creates a new `ArcFunction` that
281 /// captures a reference-counted clone. Types implementing `Clone`
282 /// can override this method to provide more efficient conversions.
283 ///
284 /// # Returns
285 ///
286 /// Returns `ArcFunction<T, R>`
287 ///
288 /// # Examples
289 ///
290 /// ```rust
291 /// use qubit_function::{ArcFunction, Function};
292 ///
293 /// let double = ArcFunction::new(|x: &i32| x * 2);
294 /// let arc = double.to_arc();
295 ///
296 /// // Original function still usable
297 /// assert_eq!(double.apply(&21), 42);
298 /// assert_eq!(arc.apply(&21), 42);
299 /// ```
300 fn to_arc(&self) -> ArcFunction<T, R>
301 where
302 Self: Clone + Send + Sync + 'static,
303 {
304 self.clone().into_arc()
305 }
306
307 /// Converts function to a closure without consuming self
308 ///
309 /// **📌 Borrows `&self`**: The original function remains usable
310 /// after calling this method.
311 ///
312 /// # Default Implementation
313 ///
314 /// The default implementation creates a closure that captures a
315 /// clone of `self` and calls its `transform` method. Types can
316 /// override this method to provide more efficient conversions.
317 ///
318 /// # Returns
319 ///
320 /// Returns a closure that implements `Fn(&T) -> R`
321 ///
322 /// # Examples
323 ///
324 /// ```rust
325 /// use qubit_function::{ArcFunction, Function};
326 ///
327 /// let double = ArcFunction::new(|x: &i32| x * 2);
328 /// let closure = double.to_fn();
329 ///
330 /// // Original function still usable
331 /// assert_eq!(double.apply(&21), 42);
332 /// assert_eq!(closure(&21), 42);
333 /// ```
334 fn to_fn(&self) -> impl Fn(&T) -> R
335 where
336 Self: Clone + 'static,
337 {
338 self.clone().into_fn()
339 }
340
341 /// Convert to FunctionOnce without consuming self
342 ///
343 /// **⚠️ Requires Clone**: This method requires `Self` to implement `Clone`.
344 /// Clones the current function and converts the clone to a one-time function.
345 ///
346 /// # Returns
347 ///
348 /// Returns a `BoxFunctionOnce<T, R>`
349 ///
350 /// # Examples
351 ///
352 /// ```rust
353 ///
354 /// use qubit_function::{Function, FunctionOnce, RcFunction};
355 ///
356 /// fn takes_once<F: FunctionOnce<i32, i32>>(func: F, value: &i32) -> i32 {
357 /// func.apply(value)
358 /// }
359 ///
360 /// let func = RcFunction::new(|x: &i32| x * 2);
361 /// let result = takes_once(func.to_once(), &5);
362 /// assert_eq!(result, 10);
363 /// ```
364 fn to_once(&self) -> BoxFunctionOnce<T, R>
365 where
366 Self: Clone + 'static,
367 {
368 self.clone().into_once()
369 }
370}
371
372// ============================================================================
373// BoxFunction - Box<dyn Fn(&T) -> R>
374// ============================================================================
375
376/// BoxFunction - function wrapper based on `Box<dyn Fn>`
377///
378/// A function wrapper that provides single ownership with reusable
379/// transformation. The function consumes the input and can be called
380/// multiple times.
381///
382/// # Features
383///
384/// - **Based on**: `Box<dyn Fn(&T) -> R>`
385/// - **Ownership**: Single ownership, cannot be cloned
386/// - **Reusability**: Can be called multiple times (each call consumes its
387/// input)
388/// - **Thread Safety**: Not thread-safe (no `Send + Sync` requirement)
389///
390/// # Author
391///
392/// Haixing Hu
393pub struct BoxFunction<T, R> {
394 function: Box<dyn Fn(&T) -> R>,
395 name: Option<String>,
396}
397
398impl<T, R> BoxFunction<T, R> {
399 // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
400 impl_function_common_methods!(
401 BoxFunction<T, R>,
402 (Fn(&T) -> R + 'static),
403 |f| Box::new(f)
404 );
405
406 // Generates: when(), and_then(), compose()
407 impl_box_function_methods!(
408 BoxFunction<T, R>,
409 BoxConditionalFunction,
410 Function
411 );
412}
413
414// Generates: constant() method for BoxFunction<T, R>
415impl_function_constant_method!(BoxFunction<T, R>, 'static);
416
417// Generates: identity() method for BoxFunction<T, T>
418impl_function_identity_method!(BoxFunction<T, T>);
419
420// Generates: Debug and Display implementations for BoxFunction<T, R>
421impl_function_debug_display!(BoxFunction<T, R>);
422
423// Implement Function trait for BoxFunction<T, R>
424impl<T, R> Function<T, R> for BoxFunction<T, R> {
425 fn apply(&self, t: &T) -> R {
426 (self.function)(t)
427 }
428
429 // Generates: into_box(), into_rc(), into_fn(), into_once()
430 impl_box_conversions!(
431 BoxFunction<T, R>,
432 RcFunction,
433 Fn(&T) -> R,
434 BoxFunctionOnce
435 );
436}
437
438// ============================================================================
439// RcFunction - Rc<dyn Fn(&T) -> R>
440// ============================================================================
441
442/// RcFunction - single-threaded function wrapper
443///
444/// A single-threaded, clonable function wrapper optimized for scenarios
445/// that require sharing without thread-safety overhead.
446///
447/// # Features
448///
449/// - **Based on**: `Rc<dyn Fn(&T) -> R>`
450/// - **Ownership**: Shared ownership via reference counting (non-atomic)
451/// - **Reusability**: Can be called multiple times (each call consumes its
452/// input)
453/// - **Thread Safety**: Not thread-safe (no `Send + Sync`)
454/// - **Clonable**: Cheap cloning via `Rc::clone`
455///
456/// # Author
457///
458/// Haixing Hu
459pub struct RcFunction<T, R> {
460 function: Rc<dyn Fn(&T) -> R>,
461 name: Option<String>,
462}
463
464impl<T, R> RcFunction<T, R> {
465 // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
466 impl_function_common_methods!(
467 RcFunction<T, R>,
468 (Fn(&T) -> R + 'static),
469 |f| Rc::new(f)
470 );
471
472 // Generates: when(), and_then(), compose()
473 impl_shared_function_methods!(
474 RcFunction<T, R>,
475 RcConditionalFunction,
476 into_rc,
477 Function,
478 'static
479 );
480}
481
482// Generates: constant() method for RcFunction<T, R>
483impl_function_constant_method!(RcFunction<T, R>, 'static);
484
485// Generates: identity() method for RcFunction<T, T>
486impl_function_identity_method!(RcFunction<T, T>);
487
488// Generates: Clone implementation for RcFunction<T, R>
489impl_function_clone!(RcFunction<T, R>);
490
491// Generates: Debug and Display implementations for RcFunction<T, R>
492impl_function_debug_display!(RcFunction<T, R>);
493
494// Implement Function trait for RcFunction<T, R>
495impl<T, R> Function<T, R> for RcFunction<T, R> {
496 fn apply(&self, t: &T) -> R {
497 (self.function)(t)
498 }
499
500 // Use macro to implement conversion methods
501 impl_rc_conversions!(
502 RcFunction<T, R>,
503 BoxFunction,
504 BoxFunctionOnce,
505 Fn(t: &T) -> R
506 );
507}
508
509// ============================================================================
510// ArcFunction - Arc<dyn Fn(&T) -> R + Send + Sync>
511// ============================================================================
512
513/// ArcFunction - thread-safe function wrapper
514///
515/// A thread-safe, clonable function wrapper suitable for multi-threaded
516/// scenarios. Can be called multiple times and shared across threads.
517///
518/// # Features
519///
520/// - **Based on**: `Arc<dyn Fn(&T) -> R + Send + Sync>`
521/// - **Ownership**: Shared ownership via reference counting
522/// - **Reusability**: Can be called multiple times (each call consumes its
523/// input)
524/// - **Thread Safety**: Thread-safe (`Send + Sync` required)
525/// - **Clonable**: Cheap cloning via `Arc::clone`
526///
527/// # Author
528///
529/// Haixing Hu
530pub struct ArcFunction<T, R> {
531 function: Arc<dyn Fn(&T) -> R + Send + Sync>,
532 name: Option<String>,
533}
534
535impl<T, R> ArcFunction<T, R> {
536 // Generates: new(), new_with_name(), new_with_optional_name(), name(), set_name()
537 impl_function_common_methods!(
538 ArcFunction<T, R>,
539 (Fn(&T) -> R + Send + Sync + 'static),
540 |f| Arc::new(f)
541 );
542
543 // Generates: when(), and_then(), compose()
544 impl_shared_function_methods!(
545 ArcFunction<T, R>,
546 ArcConditionalFunction,
547 into_arc,
548 Function,
549 Send + Sync + 'static
550 );
551}
552
553// Generates: constant() method for ArcFunction<T, R>
554impl_function_constant_method!(ArcFunction<T, R>, Send + Sync + 'static);
555
556// Generates: identity() method for ArcFunction<T, T>
557impl_function_identity_method!(ArcFunction<T, T>);
558
559// Generates: Clone implementation for ArcFunction<T, R>
560impl_function_clone!(ArcFunction<T, R>);
561
562// Generates: Debug and Display implementations for ArcFunction<T, R>
563impl_function_debug_display!(ArcFunction<T, R>);
564
565// Implement Function trait for ArcFunction<T, R>
566impl<T, R> Function<T, R> for ArcFunction<T, R> {
567 fn apply(&self, t: &T) -> R {
568 (self.function)(t)
569 }
570
571 // Use macro to implement conversion methods
572 impl_arc_conversions!(
573 ArcFunction<T, R>,
574 BoxFunction,
575 RcFunction,
576 BoxFunctionOnce,
577 Fn(t: &T) -> R
578 );
579}
580
581// ============================================================================
582// Blanket implementation for standard Fn trait
583// ============================================================================
584
585// Implement Function<T, R> for any type that implements Fn(&T) -> R
586impl_closure_trait!(
587 Function<T, R>,
588 apply,
589 BoxFunctionOnce,
590 Fn(input: &T) -> R
591);
592
593// ============================================================================
594// FnFunctionOps - Extension trait for closure functions
595// ============================================================================
596
597// Generates: FnFunctionOps trait and blanket implementation
598impl_fn_ops_trait!(
599 (Fn(&T) -> R),
600 FnFunctionOps,
601 BoxFunction,
602 Function,
603 BoxConditionalFunction
604);
605
606// ============================================================================
607// BoxConditionalFunction - Box-based Conditional Function
608// ============================================================================
609
610/// BoxConditionalFunction struct
611///
612/// A conditional function that only executes when a predicate is satisfied.
613/// Uses `BoxFunction` and `BoxPredicate` for single ownership semantics.
614///
615/// This type is typically created by calling `BoxFunction::when()` and is
616/// designed to work with the `or_else()` method to create if-then-else logic.
617///
618/// # Features
619///
620/// - **Single Ownership**: Not cloneable, consumes `self` on use
621/// - **Conditional Execution**: Only transforms when predicate returns `true`
622/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
623/// - **Implements Function**: Can be used anywhere a `Function` is expected
624///
625/// # Examples
626///
627/// ## With or_else Branch
628///
629/// ```rust
630/// use qubit_function::{Function, BoxFunction};
631///
632/// let double = BoxFunction::new(|x: &i32| x * 2);
633/// let negate = BoxFunction::new(|x: &i32| -x);
634/// let conditional = double.when(|x: &i32| *x > 0).or_else(negate);
635///
636/// assert_eq!(conditional.apply(&5), 10); // when branch executed
637/// assert_eq!(conditional.apply(&-5), 5); // or_else branch executed
638/// ```
639///
640/// # Author
641///
642/// Haixing Hu
643pub struct BoxConditionalFunction<T, R> {
644 function: BoxFunction<T, R>,
645 predicate: BoxPredicate<T>,
646}
647
648// Use macro to generate conditional function implementations
649impl_box_conditional_function!(
650 BoxConditionalFunction<T, R>,
651 BoxFunction,
652 Function
653);
654
655// Use macro to generate conditional function debug and display implementations
656impl_conditional_function_debug_display!(BoxConditionalFunction<T, R>);
657
658// ============================================================================
659// RcConditionalFunction - Rc-based Conditional Function
660// ============================================================================
661
662/// RcConditionalFunction struct
663///
664/// A single-threaded conditional function that only executes when a
665/// predicate is satisfied. Uses `RcFunction` and `RcPredicate` for shared
666/// ownership within a single thread.
667///
668/// This type is typically created by calling `RcFunction::when()` and is
669/// designed to work with the `or_else()` method to create if-then-else logic.
670///
671/// # Features
672///
673/// - **Shared Ownership**: Cloneable via `Rc`, multiple owners allowed
674/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
675/// - **Conditional Execution**: Only transforms when predicate returns `true`
676/// - **No Lock Overhead**: More efficient than `ArcConditionalFunction`
677///
678/// # Examples
679///
680/// ```rust
681/// use qubit_function::{Function, RcFunction};
682///
683/// let double = RcFunction::new(|x: &i32| x * 2);
684/// let identity = RcFunction::<i32, i32>::identity();
685/// let conditional = double.when(|x: &i32| *x > 0).or_else(identity);
686///
687/// let conditional_clone = conditional.clone();
688///
689/// assert_eq!(conditional.apply(&5), 10);
690/// assert_eq!(conditional_clone.apply(&-5), -5);
691/// ```
692///
693/// # Author
694///
695/// Haixing Hu
696pub struct RcConditionalFunction<T, R> {
697 function: RcFunction<T, R>,
698 predicate: RcPredicate<T>,
699}
700
701// Use macro to generate conditional function implementations
702impl_shared_conditional_function!(
703 RcConditionalFunction<T, R>,
704 RcFunction,
705 Function,
706 'static
707);
708
709// Use macro to generate conditional function clone implementations
710impl_conditional_function_clone!(RcConditionalFunction<T, R>);
711
712// Use macro to generate conditional function debug and display implementations
713impl_conditional_function_debug_display!(RcConditionalFunction<T, R>);
714
715// ============================================================================
716// ArcConditionalFunction - Arc-based Conditional Function
717// ============================================================================
718
719/// ArcConditionalFunction struct
720///
721/// A thread-safe conditional function that only executes when a predicate is
722/// satisfied. Uses `ArcFunction` and `ArcPredicate` for shared ownership
723/// across threads.
724///
725/// This type is typically created by calling `ArcFunction::when()` and is
726/// designed to work with the `or_else()` method to create if-then-else logic.
727///
728/// # Features
729///
730/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
731/// - **Thread-Safe**: Implements `Send + Sync`, safe for concurrent use
732/// - **Conditional Execution**: Only transforms when predicate returns `true`
733/// - **Chainable**: Can add `or_else` branch to create if-then-else logic
734///
735/// # Examples
736///
737/// ```rust
738/// use qubit_function::{Function, ArcFunction};
739///
740/// let double = ArcFunction::new(|x: &i32| x * 2);
741/// let identity = ArcFunction::<i32, i32>::identity();
742/// let conditional = double.when(|x: &i32| *x > 0).or_else(identity);
743///
744/// let conditional_clone = conditional.clone();
745///
746/// assert_eq!(conditional.apply(&5), 10);
747/// assert_eq!(conditional_clone.apply(&-5), -5);
748/// ```
749///
750/// # Author
751///
752/// Haixing Hu
753pub struct ArcConditionalFunction<T, R> {
754 function: ArcFunction<T, R>,
755 predicate: ArcPredicate<T>,
756}
757
758// Use macro to generate conditional function implementations
759impl_shared_conditional_function!(
760 ArcConditionalFunction<T, R>,
761 ArcFunction,
762 Function,
763 Send + Sync + 'static
764);
765
766// Use macro to generate conditional function clone implementations
767impl_conditional_function_clone!(ArcConditionalFunction<T, R>);
768
769// Use macro to generate conditional function debug and display implementations
770impl_conditional_function_debug_display!(ArcConditionalFunction<T, R>);