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