prism3_function/mapper.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025.
4 * 3-Prism Co. Ltd.
5 *
6 * All rights reserved.
7 *
8 ******************************************************************************/
9//! # Mapper Types
10//!
11//! Provides Rust implementations of mapper traits for stateful value
12//! transformation. Mappers consume input values (taking ownership) and
13//! produce output values while allowing internal state modification.
14//!
15//! This module provides the `Mapper<T, R>` trait and three implementations:
16//!
17//! - [`BoxMapper`]: Single ownership, not cloneable
18//! - [`ArcMapper`]: Thread-safe shared ownership, cloneable
19//! - [`RcMapper`]: Single-threaded shared ownership, cloneable
20//!
21//! # Author
22//!
23//! Haixing Hu
24
25use std::cell::RefCell;
26use std::rc::Rc;
27use std::sync::{Arc, Mutex};
28
29use crate::predicate::{ArcPredicate, BoxPredicate, Predicate, RcPredicate};
30
31// ============================================================================
32// Core Trait
33// ============================================================================
34
35/// Mapper trait - transforms values from type T to type R with state
36///
37/// Defines the behavior of a stateful transformation: converting a value
38/// of type `T` to a value of type `R` by consuming the input while
39/// allowing modification of internal state. This is analogous to
40/// `FnMut(T) -> R` in Rust's standard library.
41///
42/// # Type Parameters
43///
44/// * `T` - The type of the input value (consumed)
45/// * `R` - The type of the output value
46///
47/// # Author
48///
49/// Haixing Hu
50pub trait Mapper<T, R> {
51 /// Applies the mapping to the input value to produce an output value
52 ///
53 /// # Parameters
54 ///
55 /// * `input` - The input value to transform (consumed)
56 ///
57 /// # Returns
58 ///
59 /// The transformed output value
60 fn apply(&mut self, input: T) -> R;
61
62 /// Converts to BoxMapper
63 ///
64 /// **⚠️ Consumes `self`**: The original mapper becomes unavailable
65 /// after calling this method.
66 ///
67 /// # Returns
68 ///
69 /// Returns `BoxMapper<T, R>`
70 ///
71 /// # Default Implementation
72 ///
73 /// The default implementation wraps `self` in a `BoxMapper` by creating
74 /// a new closure that calls `self.apply()`. This provides a zero-cost
75 /// abstraction for most use cases.
76 ///
77 /// # Examples
78 ///
79 /// ```rust
80 /// use prism3_function::{Mapper, BoxMapper};
81 ///
82 /// struct CustomMapper {
83 /// multiplier: i32,
84 /// }
85 ///
86 /// impl Mapper<i32, i32> for CustomMapper {
87 /// fn apply(&mut self, input: i32) -> i32 {
88 /// self.multiplier += 1;
89 /// input * self.multiplier
90 /// }
91 /// }
92 ///
93 /// let mapper = CustomMapper { multiplier: 0 };
94 /// let mut boxed = mapper.into_box();
95 /// assert_eq!(boxed.apply(10), 10); // 10 * 1
96 /// assert_eq!(boxed.apply(10), 20); // 10 * 2
97 /// ```
98 fn into_box(self) -> BoxMapper<T, R>
99 where
100 Self: Sized + 'static,
101 T: 'static,
102 R: 'static,
103 {
104 let mut mapper = self;
105 BoxMapper::new(move |t| mapper.apply(t))
106 }
107
108 /// Converts to RcMapper
109 ///
110 /// **⚠️ Consumes `self`**: The original mapper becomes unavailable
111 /// after calling this method.
112 ///
113 /// # Returns
114 ///
115 /// Returns `RcMapper<T, R>`
116 ///
117 /// # Default Implementation
118 ///
119 /// The default implementation first converts to `BoxMapper` using
120 /// `into_box()`, then wraps it in `RcMapper`. Specific implementations
121 /// may override this for better efficiency.
122 ///
123 /// # Examples
124 ///
125 /// ```rust
126 /// use prism3_function::{Mapper, RcMapper};
127 ///
128 /// struct CustomMapper {
129 /// multiplier: i32,
130 /// }
131 ///
132 /// impl Mapper<i32, i32> for CustomMapper {
133 /// fn apply(&mut self, input: i32) -> i32 {
134 /// self.multiplier += 1;
135 /// input * self.multiplier
136 /// }
137 /// }
138 ///
139 /// let mapper = CustomMapper { multiplier: 0 };
140 /// let mut rc_mapper = mapper.into_rc();
141 /// assert_eq!(rc_mapper.apply(10), 10); // 10 * 1
142 /// assert_eq!(rc_mapper.apply(10), 20); // 10 * 2
143 /// ```
144 fn into_rc(self) -> RcMapper<T, R>
145 where
146 Self: Sized + 'static,
147 T: 'static,
148 R: 'static,
149 {
150 let mut mapper = self;
151 RcMapper::new(move |t| mapper.apply(t))
152 }
153
154 /// Converts to ArcMapper
155 ///
156 /// **⚠️ Consumes `self`**: The original mapper becomes unavailable
157 /// after calling this method.
158 ///
159 /// # Returns
160 ///
161 /// Returns `ArcMapper<T, R>`
162 ///
163 /// # Default Implementation
164 ///
165 /// The default implementation wraps `self` in an `ArcMapper` by creating
166 /// a new closure that calls `self.apply()`. Note that this requires `self`
167 /// to implement `Send` due to Arc's thread-safety requirements.
168 ///
169 /// # Examples
170 ///
171 /// ```rust
172 /// use prism3_function::{Mapper, ArcMapper};
173 ///
174 /// struct CustomMapper {
175 /// multiplier: i32,
176 /// }
177 ///
178 /// impl Mapper<i32, i32> for CustomMapper {
179 /// fn apply(&mut self, input: i32) -> i32 {
180 /// self.multiplier += 1;
181 /// input * self.multiplier
182 /// }
183 /// }
184 ///
185 /// let mapper = CustomMapper { multiplier: 0 };
186 /// let mut arc_mapper = mapper.into_arc();
187 /// assert_eq!(arc_mapper.apply(10), 10); // 10 * 1
188 /// assert_eq!(arc_mapper.apply(10), 20); // 10 * 2
189 /// ```
190 fn into_arc(self) -> ArcMapper<T, R>
191 where
192 Self: Sized + Send + 'static,
193 T: Send + Sync + 'static,
194 R: Send + 'static,
195 {
196 let mut mapper = self;
197 ArcMapper::new(move |t| mapper.apply(t))
198 }
199
200 /// Converts to a closure implementing `FnMut(T) -> R`
201 ///
202 /// **⚠️ Consumes `self`**: The original mapper becomes unavailable
203 /// after calling this method.
204 ///
205 /// # Returns
206 ///
207 /// Returns an implementation of `FnMut(T) -> R`
208 ///
209 /// # Default Implementation
210 ///
211 /// The default implementation creates a new closure that calls `self.apply()`.
212 /// Specific implementations may override this for better efficiency.
213 ///
214 /// # Examples
215 ///
216 /// ```rust
217 /// use prism3_function::{Mapper, BoxMapper};
218 ///
219 /// let mapper = BoxMapper::new(|x: i32| x * 2);
220 /// let mut closure = mapper.into_fn();
221 /// assert_eq!(closure(10), 20);
222 /// assert_eq!(closure(15), 30);
223 /// ```
224 fn into_fn(self) -> impl FnMut(T) -> R
225 where
226 Self: Sized + 'static,
227 T: 'static,
228 R: 'static,
229 {
230 let mut mapper = self;
231 move |t| mapper.apply(t)
232 }
233
234 /// Non-consuming conversion to `BoxMapper`.
235 ///
236 /// Default implementation requires `Self: Clone` and wraps a cloned
237 /// instance in a `RefCell` so the returned mapper can mutate state
238 /// across calls.
239 fn to_box(&self) -> BoxMapper<T, R>
240 where
241 Self: Sized + Clone + 'static,
242 T: 'static,
243 R: 'static,
244 {
245 self.clone().into_box()
246 }
247
248 /// Non-consuming conversion to `RcMapper`.
249 ///
250 /// Default implementation clones `self` into an `Rc<RefCell<_>>` so the
251 /// resulting mapper can be shared within a single thread.
252 fn to_rc(&self) -> RcMapper<T, R>
253 where
254 Self: Sized + Clone + 'static,
255 T: 'static,
256 R: 'static,
257 {
258 self.clone().into_rc()
259 }
260
261 /// Non-consuming conversion to `ArcMapper` (thread-safe).
262 ///
263 /// Default implementation requires `Self: Clone + Send + Sync` and wraps
264 /// the cloned instance in `Arc<Mutex<_>>` so it can be used across
265 /// threads.
266 fn to_arc(&self) -> ArcMapper<T, R>
267 where
268 Self: Sized + Clone + Send + Sync + 'static,
269 T: Send + Sync + 'static,
270 R: Send + 'static,
271 {
272 self.clone().into_arc()
273 }
274
275 /// Non-consuming conversion to a closure (`FnMut(T) -> R`).
276 ///
277 /// Default implementation clones `self` into a `RefCell` and returns a
278 /// closure that calls `apply` on the interior mutable value.
279 fn to_fn(&self) -> impl FnMut(T) -> R
280 where
281 Self: Sized + Clone + 'static,
282 T: 'static,
283 R: 'static,
284 {
285 self.clone().into_fn()
286 }
287}
288
289// ============================================================================
290// BoxMapper - Box<dyn FnMut(T) -> R>
291// ============================================================================
292
293/// BoxMapper - mapper wrapper based on `Box<dyn FnMut>`
294///
295/// A mapper wrapper that provides single ownership with reusable stateful
296/// transformation. The mapper consumes the input and can be called
297/// multiple times while maintaining internal state.
298///
299/// # Features
300///
301/// - **Based on**: `Box<dyn FnMut(T) -> R>`
302/// - **Ownership**: Single ownership, cannot be cloned
303/// - **Reusability**: Can be called multiple times (each call consumes
304/// its input)
305/// - **Thread Safety**: Not thread-safe (no `Send + Sync` requirement)
306/// - **Statefulness**: Can modify internal state between calls
307///
308/// # Author
309///
310/// Haixing Hu
311pub struct BoxMapper<T, R> {
312 function: Box<dyn FnMut(T) -> R>,
313}
314
315impl<T, R> BoxMapper<T, R>
316where
317 T: 'static,
318 R: 'static,
319{
320 /// Creates a new BoxMapper
321 ///
322 /// # Parameters
323 ///
324 /// * `f` - The closure or function to wrap
325 ///
326 /// # Examples
327 ///
328 /// ```rust
329 /// use prism3_function::{BoxMapper, Mapper};
330 ///
331 /// let mut counter = 0;
332 /// let mut mapper = BoxMapper::new(move |x: i32| {
333 /// counter += 1;
334 /// x + counter
335 /// });
336 /// assert_eq!(mapper.apply(10), 11);
337 /// assert_eq!(mapper.apply(10), 12);
338 /// ```
339 pub fn new<F>(f: F) -> Self
340 where
341 F: FnMut(T) -> R + 'static,
342 {
343 BoxMapper {
344 function: Box::new(f),
345 }
346 }
347
348 // BoxMapper is intentionally not given a `to_*` specialization here
349 // because the boxed `FnMut` is not clonable and we cannot produce a
350 // non-consuming adapter from `&self` without moving ownership or
351 // requiring `Clone` on the inner function. Consumers should use the
352 // blanket `Mapper::to_*` defaults when their mapper type implements
353 // `Clone`.
354
355 /// Creates an identity mapper
356 ///
357 /// # Examples
358 ///
359 /// ```rust
360 /// use prism3_function::{BoxMapper, Mapper};
361 ///
362 /// let mut identity = BoxMapper::<i32, i32>::identity();
363 /// assert_eq!(identity.apply(42), 42);
364 /// ```
365 pub fn identity() -> BoxMapper<T, T> {
366 BoxMapper::new(|x| x)
367 }
368
369 /// Chain composition - applies self first, then after
370 ///
371 /// Creates a new mapper that applies this mapper first, then applies
372 /// the after mapper to the result. Consumes self.
373 ///
374 /// # Type Parameters
375 ///
376 /// * `S` - The output type of the after mapper
377 /// * `F` - The type of the after mapper (must implement Mapper<R, S>)
378 ///
379 /// # Parameters
380 ///
381 /// * `after` - The mapper to apply after self. **Note: This parameter
382 /// is passed by value and will transfer ownership.** If you need to
383 /// preserve the original mapper, clone it first (if it implements
384 /// `Clone`). Can be:
385 /// - A closure: `|x: R| -> S`
386 /// - A `BoxMapper<R, S>`
387 /// - An `RcMapper<R, S>`
388 /// - An `ArcMapper<R, S>`
389 /// - Any type implementing `Mapper<R, S>`
390 ///
391 /// # Returns
392 ///
393 /// A new BoxMapper representing the composition
394 ///
395 /// # Examples
396 ///
397 /// ```rust
398 /// use prism3_function::{BoxMapper, Mapper};
399 ///
400 /// let mut counter1 = 0;
401 /// let mapper1 = BoxMapper::new(move |x: i32| {
402 /// counter1 += 1;
403 /// x + counter1
404 /// });
405 ///
406 /// let mut counter2 = 0;
407 /// let mapper2 = BoxMapper::new(move |x: i32| {
408 /// counter2 += 1;
409 /// x * counter2
410 /// });
411 ///
412 /// let mut composed = mapper1.and_then(mapper2);
413 /// assert_eq!(composed.apply(10), 11); // (10 + 1) * 1
414 /// assert_eq!(composed.apply(10), 24); // (10 + 2) * 2
415 /// ```
416 pub fn and_then<S, F>(self, after: F) -> BoxMapper<T, S>
417 where
418 S: 'static,
419 F: Mapper<R, S> + 'static,
420 {
421 let mut self_mapper = self;
422 let mut after_mapper = after;
423 BoxMapper::new(move |x: T| {
424 let intermediate = self_mapper.apply(x);
425 after_mapper.apply(intermediate)
426 })
427 }
428
429 /// Reverse composition - applies before first, then self
430 ///
431 /// Creates a new mapper that applies the before mapper first, then
432 /// applies this mapper to the result. Consumes self.
433 ///
434 /// # Type Parameters
435 ///
436 /// * `S` - The input type of the before mapper
437 /// * `F` - The type of the before mapper (must implement Mapper<S, T>)
438 ///
439 /// # Parameters
440 ///
441 /// * `before` - The mapper to apply before self. **Note: This
442 /// parameter is passed by value and will transfer ownership.** If
443 /// you need to preserve the original mapper, clone it first (if it
444 /// implements `Clone`). Can be:
445 /// - A closure: `|x: S| -> T`
446 /// - A `BoxMapper<S, T>`
447 /// - An `RcMapper<S, T>`
448 /// - An `ArcMapper<S, T>`
449 /// - Any type implementing `Mapper<S, T>`
450 ///
451 /// # Returns
452 ///
453 /// A new BoxMapper representing the composition
454 ///
455 /// # Examples
456 ///
457 /// ```rust
458 /// use prism3_function::{BoxMapper, Mapper};
459 ///
460 /// let mut counter = 0;
461 /// let mapper = BoxMapper::new(move |x: i32| {
462 /// counter += 1;
463 /// x * counter
464 /// });
465 ///
466 /// let mut composed = mapper.compose(|x: i32| x + 1);
467 /// assert_eq!(composed.apply(10), 11); // (10 + 1) * 1
468 /// assert_eq!(composed.apply(10), 22); // (10 + 1) * 2
469 /// ```
470 pub fn compose<S, F>(self, before: F) -> BoxMapper<S, R>
471 where
472 S: 'static,
473 F: Mapper<S, T> + 'static,
474 {
475 let mut self_mapper = self;
476 let mut before_mapper = before;
477 BoxMapper::new(move |x: S| {
478 let intermediate = before_mapper.apply(x);
479 self_mapper.apply(intermediate)
480 })
481 }
482
483 /// Creates a conditional mapper
484 ///
485 /// Returns a mapper that only executes when a predicate is satisfied.
486 /// You must call `or_else()` to provide an alternative mapper for
487 /// when the condition is not satisfied.
488 ///
489 /// # Parameters
490 ///
491 /// * `predicate` - The condition to check. **Note: This parameter is
492 /// passed by value and will transfer ownership.** If you need to
493 /// preserve the original predicate, clone it first (if it
494 /// implements `Clone`). Can be:
495 /// - A closure: `|x: &T| -> bool`
496 /// - A function pointer: `fn(&T) -> bool`
497 /// - A `BoxPredicate<T>`
498 /// - An `RcPredicate<T>`
499 /// - An `ArcPredicate<T>`
500 /// - Any type implementing `Predicate<T>`
501 ///
502 /// # Returns
503 ///
504 /// Returns `BoxConditionalMapper<T, R>`
505 ///
506 /// # Examples
507 ///
508 /// ```rust
509 /// use prism3_function::{Mapper, BoxMapper};
510 ///
511 /// let mut counter = 0;
512 /// let mut mapper = BoxMapper::new(move |x: i32| {
513 /// counter += 1;
514 /// x * 2
515 /// })
516 /// .when(|x: &i32| *x > 10)
517 /// .or_else(|x| x + 1);
518 ///
519 /// assert_eq!(mapper.apply(15), 30); // 15 > 10, apply * 2
520 /// assert_eq!(mapper.apply(5), 6); // 5 <= 10, apply + 1
521 /// ```
522 pub fn when<P>(self, predicate: P) -> BoxConditionalMapper<T, R>
523 where
524 P: Predicate<T> + 'static,
525 {
526 BoxConditionalMapper {
527 mapper: self,
528 predicate: predicate.into_box(),
529 }
530 }
531}
532
533impl<T, R> BoxMapper<T, R>
534where
535 T: 'static,
536 R: Clone + 'static,
537{
538 /// Creates a constant mapper
539 ///
540 /// # Examples
541 ///
542 /// ```rust
543 /// use prism3_function::{BoxMapper, Mapper};
544 ///
545 /// let mut constant = BoxMapper::constant("hello");
546 /// assert_eq!(constant.apply(123), "hello");
547 /// ```
548 pub fn constant(value: R) -> BoxMapper<T, R> {
549 BoxMapper::new(move |_| value.clone())
550 }
551}
552
553impl<T, R> Mapper<T, R> for BoxMapper<T, R> {
554 fn apply(&mut self, input: T) -> R {
555 (self.function)(input)
556 }
557
558 fn into_box(self) -> BoxMapper<T, R>
559 where
560 T: 'static,
561 R: 'static,
562 {
563 // Zero-cost: directly return itself
564 self
565 }
566
567 fn into_rc(self) -> RcMapper<T, R>
568 where
569 T: 'static,
570 R: 'static,
571 {
572 let self_fn = self.function;
573 RcMapper::new(self_fn)
574 }
575
576 // do NOT override Mapper::into_arc() because BoxMapper is not Send + Sync
577 // and calling BoxMapper::into_arc() will cause a compile error
578
579 fn into_fn(self) -> impl FnMut(T) -> R
580 where
581 T: 'static,
582 R: 'static,
583 {
584 // Zero-cost: directly return the boxed function
585 self.function
586 }
587
588 // do NOT override Mapper::to_xxx() because BoxMapper is not Clone
589 // and calling BoxMapper::to_xxx() will cause a compile error
590}
591
592// ============================================================================
593// BoxConditionalMapper - Box-based Conditional Mapper
594// ============================================================================
595
596/// BoxConditionalMapper struct
597///
598/// A conditional mapper that only executes when a predicate is satisfied.
599/// Uses `BoxMapper` and `BoxPredicate` for single ownership semantics.
600///
601/// This type is typically created by calling `BoxMapper::when()` and is
602/// designed to work with the `or_else()` method to create if-then-else
603/// logic.
604///
605/// # Features
606///
607/// - **Single Ownership**: Not cloneable, consumes `self` on use
608/// - **Conditional Execution**: Only maps when predicate returns `true`
609/// - **Chainable**: Can add `or_else` branch to create if-then-else
610/// logic
611/// - **Implements Mapper**: Can be used anywhere a `Mapper` is expected
612///
613/// # Examples
614///
615/// ```rust
616/// use prism3_function::{Mapper, BoxMapper};
617///
618/// let mut high_count = 0;
619/// let mut low_count = 0;
620///
621/// let mut mapper = BoxMapper::new(move |x: i32| {
622/// high_count += 1;
623/// x * 2
624/// })
625/// .when(|x: &i32| *x >= 10)
626/// .or_else(move |x| {
627/// low_count += 1;
628/// x + 1
629/// });
630///
631/// assert_eq!(mapper.apply(15), 30); // when branch executed
632/// assert_eq!(mapper.apply(5), 6); // or_else branch executed
633/// ```
634///
635/// # Author
636///
637/// Haixing Hu
638pub struct BoxConditionalMapper<T, R> {
639 mapper: BoxMapper<T, R>,
640 predicate: BoxPredicate<T>,
641}
642
643impl<T, R> BoxConditionalMapper<T, R>
644where
645 T: 'static,
646 R: 'static,
647{
648 /// Adds an else branch
649 ///
650 /// Executes the original mapper when the condition is satisfied,
651 /// otherwise executes else_mapper.
652 ///
653 /// # Parameters
654 ///
655 /// * `else_mapper` - The mapper for the else branch, can be:
656 /// - Closure: `|x: T| -> R`
657 /// - `BoxMapper<T, R>`, `RcMapper<T, R>`, `ArcMapper<T, R>`
658 /// - Any type implementing `Mapper<T, R>`
659 ///
660 /// # Returns
661 ///
662 /// Returns the composed `BoxMapper<T, R>`
663 ///
664 /// # Examples
665 ///
666 /// ```rust
667 /// use prism3_function::{Mapper, BoxMapper};
668 ///
669 /// let mut mapper = BoxMapper::new(|x: i32| x * 2)
670 /// .when(|x: &i32| *x > 0)
671 /// .or_else(|x: i32| -x);
672 ///
673 /// assert_eq!(mapper.apply(5), 10); // Condition satisfied
674 /// assert_eq!(mapper.apply(-5), 5); // Condition not satisfied
675 /// ```
676 pub fn or_else<F>(self, mut else_mapper: F) -> BoxMapper<T, R>
677 where
678 F: Mapper<T, R> + 'static,
679 {
680 let pred = self.predicate;
681 let mut then_mapper = self.mapper;
682 BoxMapper::new(move |t| {
683 if pred.test(&t) {
684 then_mapper.apply(t)
685 } else {
686 else_mapper.apply(t)
687 }
688 })
689 }
690}
691
692// ============================================================================
693// ArcMapper - Arc<Mutex<dyn FnMut(T) -> R + Send>>
694// ============================================================================
695
696/// ArcMapper - thread-safe mapper wrapper
697///
698/// A thread-safe, clonable mapper wrapper suitable for multi-threaded
699/// scenarios. Can be called multiple times and shared across threads
700/// while maintaining internal state.
701///
702/// # Features
703///
704/// - **Based on**: `Arc<Mutex<dyn FnMut(T) -> R + Send>>`
705/// - **Ownership**: Shared ownership via reference counting
706/// - **Reusability**: Can be called multiple times (each call consumes
707/// its input)
708/// - **Thread Safety**: Thread-safe (`Send` required)
709/// - **Clonable**: Cheap cloning via `Arc::clone`
710/// - **Statefulness**: Can modify internal state between calls
711///
712/// # Author
713///
714/// Haixing Hu
715pub struct ArcMapper<T, R> {
716 function: Arc<Mutex<dyn FnMut(T) -> R + Send>>,
717}
718
719impl<T, R> ArcMapper<T, R>
720where
721 T: Send + Sync + 'static,
722 R: Send + 'static,
723{
724 /// Creates a new ArcMapper
725 ///
726 /// # Parameters
727 ///
728 /// * `f` - The closure or function to wrap (must be Send)
729 ///
730 /// # Examples
731 ///
732 /// ```rust
733 /// use prism3_function::{ArcMapper, Mapper};
734 ///
735 /// let mut counter = 0;
736 /// let mut mapper = ArcMapper::new(move |x: i32| {
737 /// counter += 1;
738 /// x + counter
739 /// });
740 /// assert_eq!(mapper.apply(10), 11);
741 /// assert_eq!(mapper.apply(10), 12);
742 /// ```
743 pub fn new<F>(f: F) -> Self
744 where
745 F: FnMut(T) -> R + Send + 'static,
746 {
747 ArcMapper {
748 function: Arc::new(Mutex::new(f)),
749 }
750 }
751
752 /// Creates an identity mapper
753 ///
754 /// # Examples
755 ///
756 /// ```rust
757 /// use prism3_function::{ArcMapper, Mapper};
758 ///
759 /// let mut identity = ArcMapper::<i32, i32>::identity();
760 /// assert_eq!(identity.apply(42), 42);
761 /// ```
762 pub fn identity() -> ArcMapper<T, T> {
763 ArcMapper::new(|x| x)
764 }
765
766 /// Chain composition - applies self first, then after
767 ///
768 /// Creates a new mapper that applies this mapper first, then applies
769 /// the after mapper to the result. Uses &self, so original mapper
770 /// remains usable.
771 ///
772 /// # Type Parameters
773 ///
774 /// * `S` - The output type of the after mapper
775 /// * `F` - The type of the after mapper (must implement Mapper<R, S>)
776 ///
777 /// # Parameters
778 ///
779 /// * `after` - The mapper to apply after self. Can be:
780 /// - A closure: `|x: R| -> S`
781 /// - A `BoxMapper<R, S>`
782 /// - An `RcMapper<R, S>`
783 /// - An `ArcMapper<R, S>` (will be cloned internally)
784 /// - Any type implementing `Mapper<R, S> + Send`
785 ///
786 /// # Returns
787 ///
788 /// A new ArcMapper representing the composition
789 ///
790 /// # Examples
791 ///
792 /// ```rust
793 /// use prism3_function::{ArcMapper, Mapper};
794 ///
795 /// let mut counter1 = 0;
796 /// let mapper1 = ArcMapper::new(move |x: i32| {
797 /// counter1 += 1;
798 /// x + counter1
799 /// });
800 ///
801 /// let mut counter2 = 0;
802 /// let mapper2 = ArcMapper::new(move |x: i32| {
803 /// counter2 += 1;
804 /// x * counter2
805 /// });
806 ///
807 /// let mut composed = mapper1.and_then(mapper2);
808 ///
809 /// assert_eq!(composed.apply(10), 11); // (10 + 1) * 1
810 /// assert_eq!(composed.apply(10), 24); // (10 + 2) * 2
811 /// ```
812 pub fn and_then<S, F>(&self, after: F) -> ArcMapper<T, S>
813 where
814 S: Send + 'static,
815 F: Mapper<R, S> + Send + 'static,
816 {
817 let self_fn = Arc::clone(&self.function);
818 let after = Arc::new(Mutex::new(after));
819 ArcMapper {
820 function: Arc::new(Mutex::new(move |x: T| {
821 let intermediate = self_fn.lock().unwrap()(x);
822 after.lock().unwrap().apply(intermediate)
823 })),
824 }
825 }
826
827 /// Reverse composition - applies before first, then self
828 ///
829 /// Creates a new mapper that applies the before mapper first, then
830 /// applies this mapper to the result. Uses &self, so original mapper
831 /// remains usable.
832 ///
833 /// # Type Parameters
834 ///
835 /// * `S` - The input type of the before mapper
836 /// * `F` - The type of the before mapper (must implement Mapper<S, T>)
837 ///
838 /// # Parameters
839 ///
840 /// * `before` - The mapper to apply before self. Can be:
841 /// - A closure: `|x: S| -> T`
842 /// - A `BoxMapper<S, T>`
843 /// - An `RcMapper<S, T>`
844 /// - An `ArcMapper<S, T>` (will be cloned internally)
845 /// - Any type implementing `Mapper<S, T> + Send`
846 ///
847 /// # Returns
848 ///
849 /// A new ArcMapper representing the composition
850 ///
851 /// # Examples
852 ///
853 /// ```rust
854 /// use prism3_function::{ArcMapper, Mapper};
855 ///
856 /// let mut counter = 0;
857 /// let mapper = ArcMapper::new(move |x: i32| {
858 /// counter += 1;
859 /// x * counter
860 /// });
861 ///
862 /// let mut composed = mapper.compose(|x: i32| x + 1);
863 /// assert_eq!(composed.apply(10), 11); // (10 + 1) * 1
864 /// assert_eq!(composed.apply(10), 22); // (10 + 1) * 2
865 /// ```
866 pub fn compose<S, F>(&self, before: F) -> ArcMapper<S, R>
867 where
868 S: Send + 'static,
869 F: Mapper<S, T> + Send + 'static,
870 {
871 let self_fn = Arc::clone(&self.function);
872 let before = Arc::new(Mutex::new(before));
873 ArcMapper {
874 function: Arc::new(Mutex::new(move |x: S| {
875 let intermediate = before.lock().unwrap().apply(x);
876 self_fn.lock().unwrap()(intermediate)
877 })),
878 }
879 }
880
881 /// Creates a conditional mapper (thread-safe version)
882 ///
883 /// Returns a mapper that only executes when a predicate is satisfied.
884 /// You must call `or_else()` to provide an alternative mapper.
885 ///
886 /// # Parameters
887 ///
888 /// * `predicate` - The condition to check. Must be `Send`, can be:
889 /// - A closure: `|x: &T| -> bool` (requires `Send`)
890 /// - A function pointer: `fn(&T) -> bool`
891 /// - An `ArcPredicate<T>`
892 /// - Any type implementing `Predicate<T> + Send`
893 ///
894 /// # Returns
895 ///
896 /// Returns `ArcConditionalMapper<T, R>`
897 ///
898 /// # Examples
899 ///
900 /// ```rust
901 /// use prism3_function::{Mapper, ArcMapper};
902 ///
903 /// let mut counter = 0;
904 /// let mut mapper = ArcMapper::new(move |x: i32| {
905 /// counter += 1;
906 /// x * 2
907 /// })
908 /// .when(|x: &i32| *x > 10)
909 /// .or_else(|x| x + 1);
910 ///
911 /// assert_eq!(mapper.apply(15), 30); // 15 > 10, apply * 2
912 /// assert_eq!(mapper.apply(5), 6); // 5 <= 10, apply + 1
913 /// ```
914 pub fn when<P>(&self, predicate: P) -> ArcConditionalMapper<T, R>
915 where
916 P: Predicate<T> + Send + Sync + 'static,
917 {
918 ArcConditionalMapper {
919 mapper: self.clone(),
920 predicate: predicate.into_arc(),
921 }
922 }
923}
924
925impl<T, R> ArcMapper<T, R>
926where
927 T: Send + Sync + 'static,
928 R: Clone + Send + 'static,
929{
930 /// Creates a constant mapper
931 ///
932 /// # Examples
933 ///
934 /// ```rust
935 /// use prism3_function::{ArcMapper, Mapper};
936 ///
937 /// let mut constant = ArcMapper::constant("hello");
938 /// assert_eq!(constant.apply(123), "hello");
939 /// ```
940 pub fn constant(value: R) -> ArcMapper<T, R> {
941 ArcMapper::new(move |_| value.clone())
942 }
943}
944
945impl<T, R> Mapper<T, R> for ArcMapper<T, R> {
946 fn apply(&mut self, input: T) -> R {
947 (self.function.lock().unwrap())(input)
948 }
949
950 fn into_box(self) -> BoxMapper<T, R>
951 where
952 T: 'static,
953 R: 'static,
954 {
955 BoxMapper::new(move |x| self.function.lock().unwrap()(x))
956 }
957
958 fn into_rc(self) -> RcMapper<T, R>
959 where
960 T: 'static,
961 R: 'static,
962 {
963 RcMapper::new(move |x| self.function.lock().unwrap()(x))
964 }
965
966 fn into_arc(self) -> ArcMapper<T, R>
967 where
968 T: Send + Sync + 'static,
969 R: Send + 'static,
970 {
971 // Zero-cost: directly return itself
972 self
973 }
974
975 fn into_fn(self) -> impl FnMut(T) -> R
976 where
977 T: 'static,
978 R: 'static,
979 {
980 // Efficient: use Arc cloning to create a closure
981 move |input: T| (self.function.lock().unwrap())(input)
982 }
983
984 fn to_box(&self) -> BoxMapper<T, R>
985 where
986 T: 'static,
987 R: 'static,
988 {
989 let self_fn = self.function.clone();
990 BoxMapper::new(move |x| self_fn.lock().unwrap()(x))
991 }
992
993 fn to_rc(&self) -> RcMapper<T, R>
994 where
995 T: 'static,
996 R: 'static,
997 {
998 let self_fn = self.function.clone();
999 RcMapper::new(move |x| self_fn.lock().unwrap()(x))
1000 }
1001
1002 fn to_arc(&self) -> ArcMapper<T, R>
1003 where
1004 T: Send + Sync + 'static,
1005 R: Send + 'static,
1006 {
1007 self.clone()
1008 }
1009
1010 fn to_fn(&self) -> impl FnMut(T) -> R
1011 where
1012 T: 'static,
1013 R: 'static,
1014 {
1015 let self_fn = self.function.clone();
1016 move |input: T| self_fn.lock().unwrap()(input)
1017 }
1018}
1019
1020impl<T, R> Clone for ArcMapper<T, R> {
1021 fn clone(&self) -> Self {
1022 ArcMapper {
1023 function: Arc::clone(&self.function),
1024 }
1025 }
1026}
1027
1028// ============================================================================
1029// ArcConditionalMapper - Arc-based Conditional Mapper
1030// ============================================================================
1031
1032/// ArcConditionalMapper struct
1033///
1034/// A thread-safe conditional mapper that only executes when a predicate
1035/// is satisfied. Uses `ArcMapper` and `ArcPredicate` for shared
1036/// ownership across threads.
1037///
1038/// This type is typically created by calling `ArcMapper::when()` and is
1039/// designed to work with the `or_else()` method to create if-then-else
1040/// logic.
1041///
1042/// # Features
1043///
1044/// - **Shared Ownership**: Cloneable via `Arc`, multiple owners allowed
1045/// - **Thread-Safe**: Implements `Send`, safe for concurrent use
1046/// - **Conditional Execution**: Only maps when predicate returns `true`
1047/// - **Chainable**: Can add `or_else` branch to create if-then-else
1048/// logic
1049///
1050/// # Examples
1051///
1052/// ```rust
1053/// use prism3_function::{Mapper, ArcMapper};
1054///
1055/// let mut mapper = ArcMapper::new(|x: i32| x * 2)
1056/// .when(|x: &i32| *x > 0)
1057/// .or_else(|x: i32| -x);
1058///
1059/// let mut mapper_clone = mapper.clone();
1060///
1061/// assert_eq!(mapper.apply(5), 10);
1062/// assert_eq!(mapper_clone.apply(-5), 5);
1063/// ```
1064///
1065/// # Author
1066///
1067/// Haixing Hu
1068pub struct ArcConditionalMapper<T, R> {
1069 mapper: ArcMapper<T, R>,
1070 predicate: ArcPredicate<T>,
1071}
1072
1073impl<T, R> ArcConditionalMapper<T, R>
1074where
1075 T: Send + Sync + 'static,
1076 R: Send + 'static,
1077{
1078 /// Adds an else branch (thread-safe version)
1079 ///
1080 /// Executes the original mapper when the condition is satisfied,
1081 /// otherwise executes else_mapper.
1082 ///
1083 /// # Parameters
1084 ///
1085 /// * `else_mapper` - The mapper for the else branch, can be:
1086 /// - Closure: `|x: T| -> R` (must be `Send`)
1087 /// - `ArcMapper<T, R>`, `BoxMapper<T, R>`
1088 /// - Any type implementing `Mapper<T, R> + Send`
1089 ///
1090 /// # Returns
1091 ///
1092 /// Returns the composed `ArcMapper<T, R>`
1093 ///
1094 /// # Examples
1095 ///
1096 /// ```rust
1097 /// use prism3_function::{Mapper, ArcMapper};
1098 ///
1099 /// let mut mapper = ArcMapper::new(|x: i32| x * 2)
1100 /// .when(|x: &i32| *x > 0)
1101 /// .or_else(|x: i32| -x);
1102 ///
1103 /// assert_eq!(mapper.apply(5), 10);
1104 /// assert_eq!(mapper.apply(-5), 5);
1105 /// ```
1106 pub fn or_else<F>(self, else_mapper: F) -> ArcMapper<T, R>
1107 where
1108 F: Mapper<T, R> + Send + 'static,
1109 {
1110 let pred = self.predicate;
1111 let then_mapper = self.mapper;
1112 let else_mapper = Arc::new(Mutex::new(else_mapper));
1113 ArcMapper {
1114 function: Arc::new(Mutex::new(move |t| {
1115 if pred.test(&t) {
1116 then_mapper.function.lock().unwrap()(t)
1117 } else {
1118 else_mapper.lock().unwrap().apply(t)
1119 }
1120 })),
1121 }
1122 }
1123}
1124
1125impl<T, R> Clone for ArcConditionalMapper<T, R> {
1126 /// Clones the conditional mapper
1127 ///
1128 /// Creates a new instance that shares the underlying mapper and
1129 /// predicate with the original instance.
1130 fn clone(&self) -> Self {
1131 Self {
1132 mapper: self.mapper.clone(),
1133 predicate: self.predicate.clone(),
1134 }
1135 }
1136}
1137
1138// ============================================================================
1139// RcMapper - Rc<RefCell<dyn FnMut(T) -> R>>
1140// ============================================================================
1141
1142/// RcMapper - single-threaded mapper wrapper
1143///
1144/// A single-threaded, clonable mapper wrapper optimized for scenarios
1145/// that require sharing without thread-safety overhead.
1146///
1147/// # Features
1148///
1149/// - **Based on**: `Rc<RefCell<dyn FnMut(T) -> R>>`
1150/// - **Ownership**: Shared ownership via reference counting (non-atomic)
1151/// - **Reusability**: Can be called multiple times (each call consumes
1152/// its input)
1153/// - **Thread Safety**: Not thread-safe (no `Send + Sync`)
1154/// - **Clonable**: Cheap cloning via `Rc::clone`
1155/// - **Statefulness**: Can modify internal state between calls
1156///
1157/// # Author
1158///
1159/// Haixing Hu
1160pub struct RcMapper<T, R> {
1161 function: Rc<RefCell<dyn FnMut(T) -> R>>,
1162}
1163
1164impl<T, R> RcMapper<T, R>
1165where
1166 T: 'static,
1167 R: 'static,
1168{
1169 /// Creates a new RcMapper
1170 ///
1171 /// # Parameters
1172 ///
1173 /// * `f` - The closure or function to wrap
1174 ///
1175 /// # Examples
1176 ///
1177 /// ```rust
1178 /// use prism3_function::{RcMapper, Mapper};
1179 ///
1180 /// let mut counter = 0;
1181 /// let mut mapper = RcMapper::new(move |x: i32| {
1182 /// counter += 1;
1183 /// x + counter
1184 /// });
1185 /// assert_eq!(mapper.apply(10), 11);
1186 /// assert_eq!(mapper.apply(10), 12);
1187 /// ```
1188 pub fn new<F>(f: F) -> Self
1189 where
1190 F: FnMut(T) -> R + 'static,
1191 {
1192 RcMapper {
1193 function: Rc::new(RefCell::new(f)),
1194 }
1195 }
1196
1197 /// Creates an identity mapper
1198 ///
1199 /// # Examples
1200 ///
1201 /// ```rust
1202 /// use prism3_function::{RcMapper, Mapper};
1203 ///
1204 /// let mut identity = RcMapper::<i32, i32>::identity();
1205 /// assert_eq!(identity.apply(42), 42);
1206 /// ```
1207 pub fn identity() -> RcMapper<T, T> {
1208 RcMapper::new(|x| x)
1209 }
1210
1211 /// Chain composition - applies self first, then after
1212 ///
1213 /// Creates a new mapper that applies this mapper first, then applies
1214 /// the after mapper to the result. Uses &self, so original mapper
1215 /// remains usable.
1216 ///
1217 /// # Type Parameters
1218 ///
1219 /// * `S` - The output type of the after mapper
1220 /// * `F` - The type of the after mapper (must implement Mapper<R, S>)
1221 ///
1222 /// # Parameters
1223 ///
1224 /// * `after` - The mapper to apply after self. Can be:
1225 /// - A closure: `|x: R| -> S`
1226 /// - A `BoxMapper<R, S>`
1227 /// - An `RcMapper<R, S>` (will be cloned internally)
1228 /// - An `ArcMapper<R, S>`
1229 /// - Any type implementing `Mapper<R, S>`
1230 ///
1231 /// # Returns
1232 ///
1233 /// A new RcMapper representing the composition
1234 ///
1235 /// # Examples
1236 ///
1237 /// ```rust
1238 /// use prism3_function::{RcMapper, Mapper};
1239 ///
1240 /// let mut counter1 = 0;
1241 /// let mapper1 = RcMapper::new(move |x: i32| {
1242 /// counter1 += 1;
1243 /// x + counter1
1244 /// });
1245 ///
1246 /// let mut counter2 = 0;
1247 /// let mapper2 = RcMapper::new(move |x: i32| {
1248 /// counter2 += 1;
1249 /// x * counter2
1250 /// });
1251 ///
1252 /// let mut composed = mapper1.and_then(mapper2);
1253 ///
1254 /// assert_eq!(composed.apply(10), 11); // (10 + 1) * 1
1255 /// assert_eq!(composed.apply(10), 24); // (10 + 2) * 2
1256 /// ```
1257 pub fn and_then<S, F>(&self, after: F) -> RcMapper<T, S>
1258 where
1259 S: 'static,
1260 F: Mapper<R, S> + 'static,
1261 {
1262 let self_fn = Rc::clone(&self.function);
1263 let after = Rc::new(RefCell::new(after));
1264 RcMapper {
1265 function: Rc::new(RefCell::new(move |x: T| {
1266 let intermediate = self_fn.borrow_mut()(x);
1267 after.borrow_mut().apply(intermediate)
1268 })),
1269 }
1270 }
1271
1272 /// Reverse composition - applies before first, then self
1273 ///
1274 /// Creates a new mapper that applies the before mapper first, then
1275 /// applies this mapper to the result. Uses &self, so original mapper
1276 /// remains usable.
1277 ///
1278 /// # Type Parameters
1279 ///
1280 /// * `S` - The input type of the before mapper
1281 /// * `F` - The type of the before mapper (must implement Mapper<S, T>)
1282 ///
1283 /// # Parameters
1284 ///
1285 /// * `before` - The mapper to apply before self. Can be:
1286 /// - A closure: `|x: S| -> T`
1287 /// - A `BoxMapper<S, T>`
1288 /// - An `RcMapper<S, T>` (will be cloned internally)
1289 /// - An `ArcMapper<S, T>`
1290 /// - Any type implementing `Mapper<S, T>`
1291 ///
1292 /// # Returns
1293 ///
1294 /// A new RcMapper representing the composition
1295 ///
1296 /// # Examples
1297 ///
1298 /// ```rust
1299 /// use prism3_function::{RcMapper, Mapper};
1300 ///
1301 /// let mut counter = 0;
1302 /// let mapper = RcMapper::new(move |x: i32| {
1303 /// counter += 1;
1304 /// x * counter
1305 /// });
1306 ///
1307 /// let mut composed = mapper.compose(|x: i32| x + 1);
1308 /// assert_eq!(composed.apply(10), 11); // (10 + 1) * 1
1309 /// assert_eq!(composed.apply(10), 22); // (10 + 1) * 2
1310 /// ```
1311 pub fn compose<S, F>(&self, before: F) -> RcMapper<S, R>
1312 where
1313 S: 'static,
1314 F: Mapper<S, T> + 'static,
1315 {
1316 let self_fn = Rc::clone(&self.function);
1317 let before = Rc::new(RefCell::new(before));
1318 RcMapper {
1319 function: Rc::new(RefCell::new(move |x: S| {
1320 let intermediate = before.borrow_mut().apply(x);
1321 self_fn.borrow_mut()(intermediate)
1322 })),
1323 }
1324 }
1325
1326 /// Creates a conditional mapper (single-threaded shared version)
1327 ///
1328 /// Returns a mapper that only executes when a predicate is satisfied.
1329 /// You must call `or_else()` to provide an alternative mapper.
1330 ///
1331 /// # Parameters
1332 ///
1333 /// * `predicate` - The condition to check. Can be:
1334 /// - A closure: `|x: &T| -> bool`
1335 /// - A function pointer: `fn(&T) -> bool`
1336 /// - A `BoxPredicate<T>`
1337 /// - An `RcPredicate<T>`
1338 /// - An `ArcPredicate<T>`
1339 /// - Any type implementing `Predicate<T>`
1340 ///
1341 /// # Returns
1342 ///
1343 /// Returns `RcConditionalMapper<T, R>`
1344 ///
1345 /// # Examples
1346 ///
1347 /// ```rust
1348 /// use prism3_function::{Mapper, RcMapper};
1349 ///
1350 /// let mut counter = 0;
1351 /// let mut mapper = RcMapper::new(move |x: i32| {
1352 /// counter += 1;
1353 /// x * 2
1354 /// })
1355 /// .when(|x: &i32| *x > 10)
1356 /// .or_else(|x| x + 1);
1357 ///
1358 /// assert_eq!(mapper.apply(15), 30); // 15 > 10, apply * 2
1359 /// assert_eq!(mapper.apply(5), 6); // 5 <= 10, apply + 1
1360 /// ```
1361 pub fn when<P>(self, predicate: P) -> RcConditionalMapper<T, R>
1362 where
1363 P: Predicate<T> + 'static,
1364 {
1365 RcConditionalMapper {
1366 mapper: self,
1367 predicate: predicate.into_rc(),
1368 }
1369 }
1370}
1371
1372impl<T, R> RcMapper<T, R>
1373where
1374 T: 'static,
1375 R: Clone + 'static,
1376{
1377 /// Creates a constant mapper
1378 ///
1379 /// # Examples
1380 ///
1381 /// ```rust
1382 /// use prism3_function::{RcMapper, Mapper};
1383 ///
1384 /// let mut constant = RcMapper::constant("hello");
1385 /// assert_eq!(constant.apply(123), "hello");
1386 /// ```
1387 pub fn constant(value: R) -> RcMapper<T, R> {
1388 RcMapper::new(move |_| value.clone())
1389 }
1390}
1391
1392impl<T, R> Mapper<T, R> for RcMapper<T, R> {
1393 fn apply(&mut self, input: T) -> R {
1394 (self.function.borrow_mut())(input)
1395 }
1396
1397 fn into_box(self) -> BoxMapper<T, R>
1398 where
1399 T: 'static,
1400 R: 'static,
1401 {
1402 BoxMapper {
1403 function: Box::new(move |x| self.function.borrow_mut()(x)),
1404 }
1405 }
1406
1407 fn into_rc(self) -> RcMapper<T, R>
1408 where
1409 T: 'static,
1410 R: 'static,
1411 {
1412 // Zero-cost: directly return itself
1413 self
1414 }
1415
1416 // do NOT override Mapper::into_arc() because RcMapper is not Send + Sync
1417 // and calling RcMapper::into_arc() will cause a compile error
1418
1419 fn into_fn(self) -> impl FnMut(T) -> R
1420 where
1421 T: 'static,
1422 R: 'static,
1423 {
1424 // Efficient: use Rc cloning to create a closure
1425 move |input: T| (self.function.borrow_mut())(input)
1426 }
1427}
1428
1429impl<T, R> Clone for RcMapper<T, R> {
1430 fn clone(&self) -> Self {
1431 RcMapper {
1432 function: Rc::clone(&self.function),
1433 }
1434 }
1435}
1436
1437// ============================================================================
1438// RcConditionalMapper - Rc-based Conditional Mapper
1439// ============================================================================
1440
1441/// RcConditionalMapper struct
1442///
1443/// A single-threaded conditional mapper that only executes when a
1444/// predicate is satisfied. Uses `RcMapper` and `RcPredicate` for shared
1445/// ownership within a single thread.
1446///
1447/// This type is typically created by calling `RcMapper::when()` and is
1448/// designed to work with the `or_else()` method to create if-then-else
1449/// logic.
1450///
1451/// # Features
1452///
1453/// - **Shared Ownership**: Cloneable via `Rc`, multiple owners allowed
1454/// - **Single-Threaded**: Not thread-safe, cannot be sent across threads
1455/// - **Conditional Execution**: Only maps when predicate returns `true`
1456/// - **No Lock Overhead**: More efficient than `ArcConditionalMapper`
1457///
1458/// # Examples
1459///
1460/// ```rust
1461/// use prism3_function::{Mapper, RcMapper};
1462///
1463/// let mut mapper = RcMapper::new(|x: i32| x * 2)
1464/// .when(|x: &i32| *x > 0)
1465/// .or_else(|x: i32| -x);
1466///
1467/// let mut mapper_clone = mapper.clone();
1468///
1469/// assert_eq!(mapper.apply(5), 10);
1470/// assert_eq!(mapper_clone.apply(-5), 5);
1471/// ```
1472///
1473/// # Author
1474///
1475/// Haixing Hu
1476pub struct RcConditionalMapper<T, R> {
1477 mapper: RcMapper<T, R>,
1478 predicate: RcPredicate<T>,
1479}
1480
1481impl<T, R> RcConditionalMapper<T, R>
1482where
1483 T: 'static,
1484 R: 'static,
1485{
1486 /// Adds an else branch (single-threaded shared version)
1487 ///
1488 /// Executes the original mapper when the condition is satisfied,
1489 /// otherwise executes else_mapper.
1490 ///
1491 /// # Parameters
1492 ///
1493 /// * `else_mapper` - The mapper for the else branch, can be:
1494 /// - Closure: `|x: T| -> R`
1495 /// - `RcMapper<T, R>`, `BoxMapper<T, R>`
1496 /// - Any type implementing `Mapper<T, R>`
1497 ///
1498 /// # Returns
1499 ///
1500 /// Returns the composed `RcMapper<T, R>`
1501 ///
1502 /// # Examples
1503 ///
1504 /// ```rust
1505 /// use prism3_function::{Mapper, RcMapper};
1506 ///
1507 /// let mut mapper = RcMapper::new(|x: i32| x * 2)
1508 /// .when(|x: &i32| *x > 0)
1509 /// .or_else(|x: i32| -x);
1510 ///
1511 /// assert_eq!(mapper.apply(5), 10);
1512 /// assert_eq!(mapper.apply(-5), 5);
1513 /// ```
1514 pub fn or_else<F>(self, else_mapper: F) -> RcMapper<T, R>
1515 where
1516 F: Mapper<T, R> + 'static,
1517 {
1518 let pred = self.predicate;
1519 let then_mapper = self.mapper;
1520 let else_mapper = Rc::new(RefCell::new(else_mapper));
1521 RcMapper {
1522 function: Rc::new(RefCell::new(move |t| {
1523 if pred.test(&t) {
1524 then_mapper.function.borrow_mut()(t)
1525 } else {
1526 else_mapper.borrow_mut().apply(t)
1527 }
1528 })),
1529 }
1530 }
1531}
1532
1533impl<T, R> Clone for RcConditionalMapper<T, R> {
1534 /// Clones the conditional mapper
1535 ///
1536 /// Creates a new instance that shares the underlying mapper and
1537 /// predicate with the original instance.
1538 fn clone(&self) -> Self {
1539 Self {
1540 mapper: self.mapper.clone(),
1541 predicate: self.predicate.clone(),
1542 }
1543 }
1544}
1545
1546// ============================================================================
1547// Blanket implementation for standard FnMut trait
1548// ============================================================================
1549
1550/// Implement Mapper<T, R> for any type that implements FnMut(T) -> R
1551///
1552/// This allows closures to be used directly with our Mapper trait
1553/// without wrapping.
1554///
1555/// # Examples
1556///
1557/// ```rust
1558/// use prism3_function::Mapper;
1559///
1560/// let mut counter = 0;
1561/// let mut mapper = |x: i32| {
1562/// counter += 1;
1563/// x + counter
1564/// };
1565///
1566/// assert_eq!(mapper.apply(10), 11);
1567/// assert_eq!(mapper.apply(10), 12);
1568/// ```
1569///
1570/// # Author
1571///
1572/// Haixing Hu
1573impl<F, T, R> Mapper<T, R> for F
1574where
1575 F: FnMut(T) -> R,
1576 T: 'static,
1577 R: 'static,
1578{
1579 fn apply(&mut self, input: T) -> R {
1580 self(input)
1581 }
1582
1583 fn into_box(self) -> BoxMapper<T, R>
1584 where
1585 Self: Sized + 'static,
1586 {
1587 BoxMapper::new(self)
1588 }
1589
1590 fn into_rc(self) -> RcMapper<T, R>
1591 where
1592 Self: Sized + 'static,
1593 {
1594 RcMapper::new(self)
1595 }
1596
1597 fn into_arc(self) -> ArcMapper<T, R>
1598 where
1599 Self: Sized + Send + 'static,
1600 T: Send + Sync + 'static,
1601 R: Send + 'static,
1602 {
1603 ArcMapper::new(self)
1604 }
1605
1606 fn into_fn(self) -> impl FnMut(T) -> R
1607 where
1608 Self: Sized + 'static,
1609 T: 'static,
1610 R: 'static,
1611 {
1612 // Zero-cost: directly return itself (the closure)
1613 self
1614 }
1615
1616 /// Non-consuming conversion to `BoxMapper` for closures.
1617 ///
1618 /// We can create a `BoxMapper` by boxing the closure and returning a
1619 /// new `BoxMapper`. This does not require `Clone` because we consume
1620 /// the closure value passed by the caller when they call this
1621 /// method. For `&self`-style non-consuming `to_*` adapters, users can
1622 /// use the `Mapper::to_*` defaults which clone the closure when
1623 /// possible.
1624 fn to_box(&self) -> BoxMapper<T, R>
1625 where
1626 Self: Sized + Clone + 'static,
1627 T: 'static,
1628 R: 'static,
1629 {
1630 // Clone the closure into a RefCell to allow interior mutability
1631 // across calls.
1632 let cell = RefCell::new(self.clone());
1633 BoxMapper::new(move |input: T| cell.borrow_mut().apply(input))
1634 }
1635
1636 fn to_rc(&self) -> RcMapper<T, R>
1637 where
1638 Self: Sized + Clone + 'static,
1639 T: 'static,
1640 R: 'static,
1641 {
1642 let cell = Rc::new(RefCell::new(self.clone()));
1643 RcMapper::new(move |input: T| cell.borrow_mut().apply(input))
1644 }
1645
1646 fn to_arc(&self) -> ArcMapper<T, R>
1647 where
1648 Self: Sized + Clone + Send + Sync + 'static,
1649 T: Send + Sync + 'static,
1650 R: Send + 'static,
1651 {
1652 let cell = Arc::new(Mutex::new(self.clone()));
1653 ArcMapper::new(move |input: T| cell.lock().unwrap().apply(input))
1654 }
1655
1656 fn to_fn(&self) -> impl FnMut(T) -> R
1657 where
1658 Self: Sized + Clone + 'static,
1659 T: 'static,
1660 R: 'static,
1661 {
1662 let cell = RefCell::new(self.clone());
1663 move |input: T| cell.borrow_mut().apply(input)
1664 }
1665}
1666
1667// ============================================================================
1668// FnMapperOps - Extension trait for closure mappers
1669// ============================================================================
1670
1671/// Extension trait for closures implementing `FnMut(T) -> R`
1672///
1673/// Provides composition methods (`and_then`, `compose`, `when`) for
1674/// closures without requiring explicit wrapping in `BoxMapper`,
1675/// `RcMapper`, or `ArcMapper`.
1676///
1677/// This trait is automatically implemented for all closures that
1678/// implement `FnMut(T) -> R`.
1679///
1680/// # Design Rationale
1681///
1682/// While closures automatically implement `Mapper<T, R>` through blanket
1683/// implementation, they don't have access to instance methods like
1684/// `and_then`, `compose`, and `when`. This extension trait provides
1685/// those methods, returning `BoxMapper` for maximum flexibility.
1686///
1687/// # Examples
1688///
1689/// ## Chain composition with and_then
1690///
1691/// ```rust
1692/// use prism3_function::{Mapper, FnMapperOps};
1693///
1694/// let mut counter1 = 0;
1695/// let mapper1 = move |x: i32| {
1696/// counter1 += 1;
1697/// x + counter1
1698/// };
1699///
1700/// let mut counter2 = 0;
1701/// let mapper2 = move |x: i32| {
1702/// counter2 += 1;
1703/// x * counter2
1704/// };
1705///
1706/// let mut composed = mapper1.and_then(mapper2);
1707/// assert_eq!(composed.apply(10), 11); // (10 + 1) * 1
1708/// ```
1709///
1710/// ## Reverse composition with compose
1711///
1712/// ```rust
1713/// use prism3_function::{Mapper, FnMapperOps};
1714///
1715/// let mut counter = 0;
1716/// let mapper = move |x: i32| {
1717/// counter += 1;
1718/// x * counter
1719/// };
1720///
1721/// let mut composed = mapper.compose(|x: i32| x + 1);
1722/// assert_eq!(composed.apply(10), 11); // (10 + 1) * 1
1723/// ```
1724///
1725/// ## Conditional mapping with when
1726///
1727/// ```rust
1728/// use prism3_function::{Mapper, FnMapperOps};
1729///
1730/// let mut mapper = (|x: i32| x * 2)
1731/// .when(|x: &i32| *x > 0)
1732/// .or_else(|x: i32| -x);
1733///
1734/// assert_eq!(mapper.apply(5), 10);
1735/// assert_eq!(mapper.apply(-5), 5);
1736/// ```
1737///
1738/// # Author
1739///
1740/// Haixing Hu
1741pub trait FnMapperOps<T, R>: FnMut(T) -> R + Sized + 'static {
1742 /// Chain composition - applies self first, then after
1743 ///
1744 /// Creates a new mapper that applies this mapper first, then applies
1745 /// the after mapper to the result. Consumes self and returns a
1746 /// `BoxMapper`.
1747 ///
1748 /// # Type Parameters
1749 ///
1750 /// * `S` - The output type of the after mapper
1751 /// * `F` - The type of the after mapper (must implement Mapper<R, S>)
1752 ///
1753 /// # Parameters
1754 ///
1755 /// * `after` - The mapper to apply after self. Can be:
1756 /// - A closure: `|x: R| -> S`
1757 /// - A `BoxMapper<R, S>`
1758 /// - An `RcMapper<R, S>`
1759 /// - An `ArcMapper<R, S>`
1760 /// - Any type implementing `Mapper<R, S>`
1761 ///
1762 /// # Returns
1763 ///
1764 /// A new `BoxMapper<T, S>` representing the composition
1765 ///
1766 /// # Examples
1767 ///
1768 /// ```rust
1769 /// use prism3_function::{Mapper, FnMapperOps, BoxMapper};
1770 ///
1771 /// let mut counter1 = 0;
1772 /// let mapper1 = move |x: i32| {
1773 /// counter1 += 1;
1774 /// x + counter1
1775 /// };
1776 ///
1777 /// let mut counter2 = 0;
1778 /// let mapper2 = BoxMapper::new(move |x: i32| {
1779 /// counter2 += 1;
1780 /// x * counter2
1781 /// });
1782 ///
1783 /// let mut composed = mapper1.and_then(mapper2);
1784 /// assert_eq!(composed.apply(10), 11);
1785 /// ```
1786 fn and_then<S, F>(self, after: F) -> BoxMapper<T, S>
1787 where
1788 S: 'static,
1789 F: Mapper<R, S> + 'static,
1790 T: 'static,
1791 R: 'static,
1792 {
1793 BoxMapper::new(self).and_then(after)
1794 }
1795
1796 /// Reverse composition - applies before first, then self
1797 ///
1798 /// Creates a new mapper that applies the before mapper first, then
1799 /// applies this mapper to the result. Consumes self and returns a
1800 /// `BoxMapper`.
1801 ///
1802 /// # Type Parameters
1803 ///
1804 /// * `S` - The input type of the before mapper
1805 /// * `F` - The type of the before mapper (must implement Mapper<S, T>)
1806 ///
1807 /// # Parameters
1808 ///
1809 /// * `before` - The mapper to apply before self. Can be:
1810 /// - A closure: `|x: S| -> T`
1811 /// - A `BoxMapper<S, T>`
1812 /// - An `RcMapper<S, T>`
1813 /// - An `ArcMapper<S, T>`
1814 /// - Any type implementing `Mapper<S, T>`
1815 ///
1816 /// # Returns
1817 ///
1818 /// A new `BoxMapper<S, R>` representing the composition
1819 ///
1820 /// # Examples
1821 ///
1822 /// ```rust
1823 /// use prism3_function::{Mapper, FnMapperOps, BoxMapper};
1824 ///
1825 /// let mut counter = 0;
1826 /// let mapper = move |x: i32| {
1827 /// counter += 1;
1828 /// x * counter
1829 /// };
1830 ///
1831 /// let before = BoxMapper::new(|x: i32| x + 1);
1832 ///
1833 /// let mut composed = mapper.compose(before);
1834 /// assert_eq!(composed.apply(10), 11); // (10 + 1) * 1
1835 /// ```
1836 fn compose<S, F>(self, before: F) -> BoxMapper<S, R>
1837 where
1838 S: 'static,
1839 F: Mapper<S, T> + 'static,
1840 T: 'static,
1841 R: 'static,
1842 {
1843 BoxMapper::new(self).compose(before)
1844 }
1845
1846 /// Creates a conditional mapper
1847 ///
1848 /// Returns a mapper that only executes when a predicate is satisfied.
1849 /// You must call `or_else()` to provide an alternative mapper for
1850 /// when the condition is not satisfied.
1851 ///
1852 /// # Parameters
1853 ///
1854 /// * `predicate` - The condition to check. Can be:
1855 /// - A closure: `|x: &T| -> bool`
1856 /// - A function pointer: `fn(&T) -> bool`
1857 /// - A `BoxPredicate<T>`
1858 /// - An `RcPredicate<T>`
1859 /// - An `ArcPredicate<T>`
1860 /// - Any type implementing `Predicate<T>`
1861 ///
1862 /// # Returns
1863 ///
1864 /// Returns `BoxConditionalMapper<T, R>`
1865 ///
1866 /// # Examples
1867 ///
1868 /// ```rust
1869 /// use prism3_function::{Mapper, FnMapperOps};
1870 ///
1871 /// let mut mapper = (|x: i32| x * 2)
1872 /// .when(|x: &i32| *x > 0)
1873 /// .or_else(|x: i32| -x);
1874 ///
1875 /// assert_eq!(mapper.apply(5), 10);
1876 /// assert_eq!(mapper.apply(-5), 5);
1877 /// ```
1878 fn when<P>(self, predicate: P) -> BoxConditionalMapper<T, R>
1879 where
1880 P: Predicate<T> + 'static,
1881 T: 'static,
1882 R: 'static,
1883 {
1884 BoxMapper::new(self).when(predicate)
1885 }
1886}
1887
1888/// Blanket implementation of FnMapperOps for all closures
1889///
1890/// Automatically implements `FnMapperOps<T, R>` for any type that
1891/// implements `FnMut(T) -> R`.
1892///
1893/// # Author
1894///
1895/// Haixing Hu
1896impl<T, R, F> FnMapperOps<T, R> for F where F: FnMut(T) -> R + 'static {}