BoxMapper

Struct BoxMapper 

Source
pub struct BoxMapper<T, R> { /* private fields */ }
Expand description

BoxMapper - mapper wrapper based on Box<dyn FnMut>

A mapper wrapper that provides single ownership with reusable stateful transformation. The mapper consumes the input and can be called multiple times while maintaining internal state.

§Features

  • Based on: Box<dyn FnMut(T) -> R>
  • Ownership: Single ownership, cannot be cloned
  • Reusability: Can be called multiple times (each call consumes its input)
  • Thread Safety: Not thread-safe (no Send + Sync requirement)
  • Statefulness: Can modify internal state between calls

§Author

Haixing Hu

Implementations§

Source§

impl<T, R> BoxMapper<T, R>
where T: 'static, R: 'static,

Source

pub fn new<F>(f: F) -> Self
where F: FnMut(T) -> R + 'static,

Creates a new BoxMapper

§Parameters
  • f - The closure or function to wrap
§Examples
use prism3_function::{BoxMapper, Mapper};

let mut counter = 0;
let mut mapper = BoxMapper::new(move |x: i32| {
    counter += 1;
    x + counter
});
assert_eq!(mapper.apply(10), 11);
assert_eq!(mapper.apply(10), 12);
Examples found in repository?
examples/mapper_demo.rs (lines 23-26)
17fn main() {
18    println!("=== Mapper Demo ===\n");
19
20    // 1. Basic BoxMapper with state
21    println!("1. BoxMapper with stateful counter:");
22    let mut counter = 0;
23    let mut mapper = BoxMapper::new(move |x: i32| {
24        counter += 1;
25        format!("Item #{}: {}", counter, x)
26    });
27
28    println!("  {}", mapper.apply(100)); // Item #1: 100
29    println!("  {}", mapper.apply(200)); // Item #2: 200
30    println!("  {}", mapper.apply(300)); // Item #3: 300
31
32    // 2. Composing mappers with and_then
33    println!("\n2. Composing mappers with and_then:");
34    let mut counter1 = 0;
35    let mapper1 = BoxMapper::new(move |x: i32| {
36        counter1 += 1;
37        x + counter1
38    });
39
40    let mut counter2 = 0;
41    let mapper2 = BoxMapper::new(move |x: i32| {
42        counter2 += 1;
43        x * counter2
44    });
45
46    let mut composed = mapper1.and_then(mapper2);
47    println!("  First call:  {}", composed.apply(10)); // (10 + 1) * 1 = 11
48    println!("  Second call: {}", composed.apply(10)); // (10 + 2) * 2 = 24
49    println!("  Third call:  {}", composed.apply(10)); // (10 + 3) * 3 = 39
50
51    // 3. Conditional mapping with when/or_else
52    println!("\n3. Conditional mapping:");
53    let mut high_count = 0;
54    let mut low_count = 0;
55
56    let mut conditional = BoxMapper::new(move |x: i32| {
57        high_count += 1;
58        format!("High[{}]: {} * 2 = {}", high_count, x, x * 2)
59    })
60    .when(|x: &i32| *x >= 10)
61    .or_else(move |x| {
62        low_count += 1;
63        format!("Low[{}]: {} + 1 = {}", low_count, x, x + 1)
64    });
65
66    println!("  {}", conditional.apply(15)); // High[1]: 15 * 2 = 30
67    println!("  {}", conditional.apply(5)); // Low[1]: 5 + 1 = 6
68    println!("  {}", conditional.apply(20)); // High[2]: 20 * 2 = 40
69
70    // 4. RcMapper for cloneable mappers
71    println!("\n4. RcMapper (cloneable, single-threaded):");
72    let mut counter = 0;
73    let mapper = RcMapper::new(move |x: i32| {
74        counter += 1;
75        x + counter
76    });
77
78    let mut mapper1 = mapper.clone();
79    let mut mapper2 = mapper.clone();
80
81    println!("  mapper1: {}", mapper1.apply(10)); // 11
82    println!("  mapper2: {}", mapper2.apply(10)); // 12
83    println!("  mapper1: {}", mapper1.apply(10)); // 13
84
85    // 5. ArcMapper for thread-safe mappers
86    println!("\n5. ArcMapper (thread-safe):");
87    let mut counter = 0;
88    let mapper = ArcMapper::new(move |x: i32| {
89        counter += 1;
90        format!("Result[{}]: {}", counter, x * 2)
91    });
92
93    let mut mapper_clone = mapper.clone();
94    println!("  Original: {}", mapper_clone.apply(5)); // Result[1]: 10
95    println!("  Clone:    {}", mapper_clone.apply(7)); // Result[2]: 14
96
97    // 6. Using FnMapperOps extension trait
98    println!("\n6. Using FnMapperOps extension trait:");
99    let mut count = 0;
100    let mut mapper = (move |x: i32| {
101        count += 1;
102        x + count
103    })
104    .and_then(|x| x * 2);
105
106    println!("  {}", mapper.apply(10)); // (10 + 1) * 2 = 22
107    println!("  {}", mapper.apply(10)); // (10 + 2) * 2 = 24
108
109    // 7. Building a complex pipeline
110    println!("\n7. Complex processing pipeline:");
111    let mut step1_count = 0;
112    let step1 = BoxMapper::new(move |x: i32| {
113        step1_count += 1;
114        format!("Step1[{}]: {}", step1_count, x)
115    });
116
117    let mut step2_count = 0;
118    let step2 = BoxMapper::new(move |s: String| {
119        step2_count += 1;
120        format!("{} -> Step2[{}]", s, step2_count)
121    });
122
123    let mut step3_count = 0;
124    let step3 = BoxMapper::new(move |s: String| {
125        step3_count += 1;
126        format!("{} -> Step3[{}]", s, step3_count)
127    });
128
129    let mut pipeline = step1.and_then(step2).and_then(step3);
130
131    println!("  {}", pipeline.apply(100));
132    println!("  {}", pipeline.apply(200));
133
134    // 7. MapperOnce implementation - consuming mappers
135    println!("\n7. MapperOnce implementation - consuming Mappers:");
136
137    // BoxMapper can be consumed as MapperOnce
138    let mut counter = 0;
139    let box_mapper = BoxMapper::new(move |x: i32| {
140        counter += 1;
141        x * counter
142    });
143    println!("  BoxMapper consumed once: {}", box_mapper.apply_once(10)); // 10 * 1 = 10
144
145    // RcMapper can be consumed as MapperOnce
146    let mut counter = 0;
147    let rc_mapper = RcMapper::new(move |x: i32| {
148        counter += 1;
149        x + counter
150    });
151    let rc_clone = rc_mapper.clone(); // Clone before consuming
152    println!("  RcMapper consumed once: {}", rc_mapper.apply_once(10)); // 10 + 1 = 11
153    println!(
154        "  RcMapper clone still works: {}",
155        rc_clone.clone().apply(10)
156    ); // 10 + 2 = 12
157
158    // ArcMapper can be consumed as MapperOnce
159    let mut counter = 0;
160    let arc_mapper = ArcMapper::new(move |x: i32| {
161        counter += 1;
162        x * counter
163    });
164    let arc_clone = arc_mapper.clone(); // Clone before consuming
165    println!("  ArcMapper consumed once: {}", arc_mapper.apply_once(10)); // 10 * 1 = 10
166    println!(
167        "  ArcMapper clone still works: {}",
168        arc_clone.clone().apply(10)
169    ); // 10 * 2 = 20
170
171    // 8. Converting to BoxMapperOnce
172    println!("\n8. Converting Mappers to BoxMapperOnce:");
173
174    let mut counter = 0;
175    let mapper = BoxMapper::new(move |x: i32| {
176        counter += 1;
177        x * counter
178    });
179    let once_mapper = mapper.into_box_once();
180    println!("  BoxMapper->BoxMapperOnce: {}", once_mapper.apply_once(5)); // 5 * 1 = 5
181
182    // RcMapper can use to_box_once() to preserve original
183    let mut counter = 0;
184    let rc_mapper = RcMapper::new(move |x: i32| {
185        counter += 1;
186        x * counter
187    });
188    let once_mapper = rc_mapper.to_box_once();
189    println!("  RcMapper->BoxMapperOnce: {}", once_mapper.apply_once(5)); // 5 * 1 = 5
190    println!(
191        "  Original RcMapper still works: {}",
192        rc_mapper.clone().apply(5)
193    ); // 5 * 2 = 10
194
195    println!("\n=== Demo Complete ===");
196}
Source

pub fn identity() -> BoxMapper<T, T>

Creates an identity mapper

§Examples
use prism3_function::{BoxMapper, Mapper};

let mut identity = BoxMapper::<i32, i32>::identity();
assert_eq!(identity.apply(42), 42);
Source

pub fn and_then<S, F>(self, after: F) -> BoxMapper<T, S>
where S: 'static, F: Mapper<R, S> + 'static,

Chain composition - applies self first, then after

Creates a new mapper that applies this mapper first, then applies the after mapper to the result. Consumes self.

§Type Parameters
  • S - The output type of the after mapper
  • F - The type of the after mapper (must implement Mapper<R, S>)
§Parameters
  • after - The mapper to apply after self. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original mapper, clone it first (if it implements Clone). Can be:
    • A closure: |x: R| -> S
    • A BoxMapper<R, S>
    • An RcMapper<R, S>
    • An ArcMapper<R, S>
    • Any type implementing Mapper<R, S>
§Returns

A new BoxMapper representing the composition

§Examples
use prism3_function::{BoxMapper, Mapper};

let mut counter1 = 0;
let mapper1 = BoxMapper::new(move |x: i32| {
    counter1 += 1;
    x + counter1
});

let mut counter2 = 0;
let mapper2 = BoxMapper::new(move |x: i32| {
    counter2 += 1;
    x * counter2
});

let mut composed = mapper1.and_then(mapper2);
assert_eq!(composed.apply(10), 11);  // (10 + 1) * 1
assert_eq!(composed.apply(10), 24);  // (10 + 2) * 2
Examples found in repository?
examples/mapper_demo.rs (line 46)
17fn main() {
18    println!("=== Mapper Demo ===\n");
19
20    // 1. Basic BoxMapper with state
21    println!("1. BoxMapper with stateful counter:");
22    let mut counter = 0;
23    let mut mapper = BoxMapper::new(move |x: i32| {
24        counter += 1;
25        format!("Item #{}: {}", counter, x)
26    });
27
28    println!("  {}", mapper.apply(100)); // Item #1: 100
29    println!("  {}", mapper.apply(200)); // Item #2: 200
30    println!("  {}", mapper.apply(300)); // Item #3: 300
31
32    // 2. Composing mappers with and_then
33    println!("\n2. Composing mappers with and_then:");
34    let mut counter1 = 0;
35    let mapper1 = BoxMapper::new(move |x: i32| {
36        counter1 += 1;
37        x + counter1
38    });
39
40    let mut counter2 = 0;
41    let mapper2 = BoxMapper::new(move |x: i32| {
42        counter2 += 1;
43        x * counter2
44    });
45
46    let mut composed = mapper1.and_then(mapper2);
47    println!("  First call:  {}", composed.apply(10)); // (10 + 1) * 1 = 11
48    println!("  Second call: {}", composed.apply(10)); // (10 + 2) * 2 = 24
49    println!("  Third call:  {}", composed.apply(10)); // (10 + 3) * 3 = 39
50
51    // 3. Conditional mapping with when/or_else
52    println!("\n3. Conditional mapping:");
53    let mut high_count = 0;
54    let mut low_count = 0;
55
56    let mut conditional = BoxMapper::new(move |x: i32| {
57        high_count += 1;
58        format!("High[{}]: {} * 2 = {}", high_count, x, x * 2)
59    })
60    .when(|x: &i32| *x >= 10)
61    .or_else(move |x| {
62        low_count += 1;
63        format!("Low[{}]: {} + 1 = {}", low_count, x, x + 1)
64    });
65
66    println!("  {}", conditional.apply(15)); // High[1]: 15 * 2 = 30
67    println!("  {}", conditional.apply(5)); // Low[1]: 5 + 1 = 6
68    println!("  {}", conditional.apply(20)); // High[2]: 20 * 2 = 40
69
70    // 4. RcMapper for cloneable mappers
71    println!("\n4. RcMapper (cloneable, single-threaded):");
72    let mut counter = 0;
73    let mapper = RcMapper::new(move |x: i32| {
74        counter += 1;
75        x + counter
76    });
77
78    let mut mapper1 = mapper.clone();
79    let mut mapper2 = mapper.clone();
80
81    println!("  mapper1: {}", mapper1.apply(10)); // 11
82    println!("  mapper2: {}", mapper2.apply(10)); // 12
83    println!("  mapper1: {}", mapper1.apply(10)); // 13
84
85    // 5. ArcMapper for thread-safe mappers
86    println!("\n5. ArcMapper (thread-safe):");
87    let mut counter = 0;
88    let mapper = ArcMapper::new(move |x: i32| {
89        counter += 1;
90        format!("Result[{}]: {}", counter, x * 2)
91    });
92
93    let mut mapper_clone = mapper.clone();
94    println!("  Original: {}", mapper_clone.apply(5)); // Result[1]: 10
95    println!("  Clone:    {}", mapper_clone.apply(7)); // Result[2]: 14
96
97    // 6. Using FnMapperOps extension trait
98    println!("\n6. Using FnMapperOps extension trait:");
99    let mut count = 0;
100    let mut mapper = (move |x: i32| {
101        count += 1;
102        x + count
103    })
104    .and_then(|x| x * 2);
105
106    println!("  {}", mapper.apply(10)); // (10 + 1) * 2 = 22
107    println!("  {}", mapper.apply(10)); // (10 + 2) * 2 = 24
108
109    // 7. Building a complex pipeline
110    println!("\n7. Complex processing pipeline:");
111    let mut step1_count = 0;
112    let step1 = BoxMapper::new(move |x: i32| {
113        step1_count += 1;
114        format!("Step1[{}]: {}", step1_count, x)
115    });
116
117    let mut step2_count = 0;
118    let step2 = BoxMapper::new(move |s: String| {
119        step2_count += 1;
120        format!("{} -> Step2[{}]", s, step2_count)
121    });
122
123    let mut step3_count = 0;
124    let step3 = BoxMapper::new(move |s: String| {
125        step3_count += 1;
126        format!("{} -> Step3[{}]", s, step3_count)
127    });
128
129    let mut pipeline = step1.and_then(step2).and_then(step3);
130
131    println!("  {}", pipeline.apply(100));
132    println!("  {}", pipeline.apply(200));
133
134    // 7. MapperOnce implementation - consuming mappers
135    println!("\n7. MapperOnce implementation - consuming Mappers:");
136
137    // BoxMapper can be consumed as MapperOnce
138    let mut counter = 0;
139    let box_mapper = BoxMapper::new(move |x: i32| {
140        counter += 1;
141        x * counter
142    });
143    println!("  BoxMapper consumed once: {}", box_mapper.apply_once(10)); // 10 * 1 = 10
144
145    // RcMapper can be consumed as MapperOnce
146    let mut counter = 0;
147    let rc_mapper = RcMapper::new(move |x: i32| {
148        counter += 1;
149        x + counter
150    });
151    let rc_clone = rc_mapper.clone(); // Clone before consuming
152    println!("  RcMapper consumed once: {}", rc_mapper.apply_once(10)); // 10 + 1 = 11
153    println!(
154        "  RcMapper clone still works: {}",
155        rc_clone.clone().apply(10)
156    ); // 10 + 2 = 12
157
158    // ArcMapper can be consumed as MapperOnce
159    let mut counter = 0;
160    let arc_mapper = ArcMapper::new(move |x: i32| {
161        counter += 1;
162        x * counter
163    });
164    let arc_clone = arc_mapper.clone(); // Clone before consuming
165    println!("  ArcMapper consumed once: {}", arc_mapper.apply_once(10)); // 10 * 1 = 10
166    println!(
167        "  ArcMapper clone still works: {}",
168        arc_clone.clone().apply(10)
169    ); // 10 * 2 = 20
170
171    // 8. Converting to BoxMapperOnce
172    println!("\n8. Converting Mappers to BoxMapperOnce:");
173
174    let mut counter = 0;
175    let mapper = BoxMapper::new(move |x: i32| {
176        counter += 1;
177        x * counter
178    });
179    let once_mapper = mapper.into_box_once();
180    println!("  BoxMapper->BoxMapperOnce: {}", once_mapper.apply_once(5)); // 5 * 1 = 5
181
182    // RcMapper can use to_box_once() to preserve original
183    let mut counter = 0;
184    let rc_mapper = RcMapper::new(move |x: i32| {
185        counter += 1;
186        x * counter
187    });
188    let once_mapper = rc_mapper.to_box_once();
189    println!("  RcMapper->BoxMapperOnce: {}", once_mapper.apply_once(5)); // 5 * 1 = 5
190    println!(
191        "  Original RcMapper still works: {}",
192        rc_mapper.clone().apply(5)
193    ); // 5 * 2 = 10
194
195    println!("\n=== Demo Complete ===");
196}
Source

pub fn compose<S, F>(self, before: F) -> BoxMapper<S, R>
where S: 'static, F: Mapper<S, T> + 'static,

Reverse composition - applies before first, then self

Creates a new mapper that applies the before mapper first, then applies this mapper to the result. Consumes self.

§Type Parameters
  • S - The input type of the before mapper
  • F - The type of the before mapper (must implement Mapper<S, T>)
§Parameters
  • before - The mapper to apply before self. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original mapper, clone it first (if it implements Clone). Can be:
    • A closure: |x: S| -> T
    • A BoxMapper<S, T>
    • An RcMapper<S, T>
    • An ArcMapper<S, T>
    • Any type implementing Mapper<S, T>
§Returns

A new BoxMapper representing the composition

§Examples
use prism3_function::{BoxMapper, Mapper};

let mut counter = 0;
let mapper = BoxMapper::new(move |x: i32| {
    counter += 1;
    x * counter
});

let mut composed = mapper.compose(|x: i32| x + 1);
assert_eq!(composed.apply(10), 11); // (10 + 1) * 1
assert_eq!(composed.apply(10), 22); // (10 + 1) * 2
Source

pub fn when<P>(self, predicate: P) -> BoxConditionalMapper<T, R>
where P: Predicate<T> + 'static,

Creates a conditional mapper

Returns a mapper that only executes when a predicate is satisfied. You must call or_else() to provide an alternative mapper for when the condition is not satisfied.

§Parameters
  • predicate - The condition to check. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original predicate, clone it first (if it implements Clone). Can be:
    • A closure: |x: &T| -> bool
    • A function pointer: fn(&T) -> bool
    • A BoxPredicate<T>
    • An RcPredicate<T>
    • An ArcPredicate<T>
    • Any type implementing Predicate<T>
§Returns

Returns BoxConditionalMapper<T, R>

§Examples
use prism3_function::{Mapper, BoxMapper};

let mut counter = 0;
let mut mapper = BoxMapper::new(move |x: i32| {
    counter += 1;
    x * 2
})
.when(|x: &i32| *x > 10)
.or_else(|x| x + 1);

assert_eq!(mapper.apply(15), 30);  // 15 > 10, apply * 2
assert_eq!(mapper.apply(5), 6);    // 5 <= 10, apply + 1
Examples found in repository?
examples/mapper_demo.rs (line 60)
17fn main() {
18    println!("=== Mapper Demo ===\n");
19
20    // 1. Basic BoxMapper with state
21    println!("1. BoxMapper with stateful counter:");
22    let mut counter = 0;
23    let mut mapper = BoxMapper::new(move |x: i32| {
24        counter += 1;
25        format!("Item #{}: {}", counter, x)
26    });
27
28    println!("  {}", mapper.apply(100)); // Item #1: 100
29    println!("  {}", mapper.apply(200)); // Item #2: 200
30    println!("  {}", mapper.apply(300)); // Item #3: 300
31
32    // 2. Composing mappers with and_then
33    println!("\n2. Composing mappers with and_then:");
34    let mut counter1 = 0;
35    let mapper1 = BoxMapper::new(move |x: i32| {
36        counter1 += 1;
37        x + counter1
38    });
39
40    let mut counter2 = 0;
41    let mapper2 = BoxMapper::new(move |x: i32| {
42        counter2 += 1;
43        x * counter2
44    });
45
46    let mut composed = mapper1.and_then(mapper2);
47    println!("  First call:  {}", composed.apply(10)); // (10 + 1) * 1 = 11
48    println!("  Second call: {}", composed.apply(10)); // (10 + 2) * 2 = 24
49    println!("  Third call:  {}", composed.apply(10)); // (10 + 3) * 3 = 39
50
51    // 3. Conditional mapping with when/or_else
52    println!("\n3. Conditional mapping:");
53    let mut high_count = 0;
54    let mut low_count = 0;
55
56    let mut conditional = BoxMapper::new(move |x: i32| {
57        high_count += 1;
58        format!("High[{}]: {} * 2 = {}", high_count, x, x * 2)
59    })
60    .when(|x: &i32| *x >= 10)
61    .or_else(move |x| {
62        low_count += 1;
63        format!("Low[{}]: {} + 1 = {}", low_count, x, x + 1)
64    });
65
66    println!("  {}", conditional.apply(15)); // High[1]: 15 * 2 = 30
67    println!("  {}", conditional.apply(5)); // Low[1]: 5 + 1 = 6
68    println!("  {}", conditional.apply(20)); // High[2]: 20 * 2 = 40
69
70    // 4. RcMapper for cloneable mappers
71    println!("\n4. RcMapper (cloneable, single-threaded):");
72    let mut counter = 0;
73    let mapper = RcMapper::new(move |x: i32| {
74        counter += 1;
75        x + counter
76    });
77
78    let mut mapper1 = mapper.clone();
79    let mut mapper2 = mapper.clone();
80
81    println!("  mapper1: {}", mapper1.apply(10)); // 11
82    println!("  mapper2: {}", mapper2.apply(10)); // 12
83    println!("  mapper1: {}", mapper1.apply(10)); // 13
84
85    // 5. ArcMapper for thread-safe mappers
86    println!("\n5. ArcMapper (thread-safe):");
87    let mut counter = 0;
88    let mapper = ArcMapper::new(move |x: i32| {
89        counter += 1;
90        format!("Result[{}]: {}", counter, x * 2)
91    });
92
93    let mut mapper_clone = mapper.clone();
94    println!("  Original: {}", mapper_clone.apply(5)); // Result[1]: 10
95    println!("  Clone:    {}", mapper_clone.apply(7)); // Result[2]: 14
96
97    // 6. Using FnMapperOps extension trait
98    println!("\n6. Using FnMapperOps extension trait:");
99    let mut count = 0;
100    let mut mapper = (move |x: i32| {
101        count += 1;
102        x + count
103    })
104    .and_then(|x| x * 2);
105
106    println!("  {}", mapper.apply(10)); // (10 + 1) * 2 = 22
107    println!("  {}", mapper.apply(10)); // (10 + 2) * 2 = 24
108
109    // 7. Building a complex pipeline
110    println!("\n7. Complex processing pipeline:");
111    let mut step1_count = 0;
112    let step1 = BoxMapper::new(move |x: i32| {
113        step1_count += 1;
114        format!("Step1[{}]: {}", step1_count, x)
115    });
116
117    let mut step2_count = 0;
118    let step2 = BoxMapper::new(move |s: String| {
119        step2_count += 1;
120        format!("{} -> Step2[{}]", s, step2_count)
121    });
122
123    let mut step3_count = 0;
124    let step3 = BoxMapper::new(move |s: String| {
125        step3_count += 1;
126        format!("{} -> Step3[{}]", s, step3_count)
127    });
128
129    let mut pipeline = step1.and_then(step2).and_then(step3);
130
131    println!("  {}", pipeline.apply(100));
132    println!("  {}", pipeline.apply(200));
133
134    // 7. MapperOnce implementation - consuming mappers
135    println!("\n7. MapperOnce implementation - consuming Mappers:");
136
137    // BoxMapper can be consumed as MapperOnce
138    let mut counter = 0;
139    let box_mapper = BoxMapper::new(move |x: i32| {
140        counter += 1;
141        x * counter
142    });
143    println!("  BoxMapper consumed once: {}", box_mapper.apply_once(10)); // 10 * 1 = 10
144
145    // RcMapper can be consumed as MapperOnce
146    let mut counter = 0;
147    let rc_mapper = RcMapper::new(move |x: i32| {
148        counter += 1;
149        x + counter
150    });
151    let rc_clone = rc_mapper.clone(); // Clone before consuming
152    println!("  RcMapper consumed once: {}", rc_mapper.apply_once(10)); // 10 + 1 = 11
153    println!(
154        "  RcMapper clone still works: {}",
155        rc_clone.clone().apply(10)
156    ); // 10 + 2 = 12
157
158    // ArcMapper can be consumed as MapperOnce
159    let mut counter = 0;
160    let arc_mapper = ArcMapper::new(move |x: i32| {
161        counter += 1;
162        x * counter
163    });
164    let arc_clone = arc_mapper.clone(); // Clone before consuming
165    println!("  ArcMapper consumed once: {}", arc_mapper.apply_once(10)); // 10 * 1 = 10
166    println!(
167        "  ArcMapper clone still works: {}",
168        arc_clone.clone().apply(10)
169    ); // 10 * 2 = 20
170
171    // 8. Converting to BoxMapperOnce
172    println!("\n8. Converting Mappers to BoxMapperOnce:");
173
174    let mut counter = 0;
175    let mapper = BoxMapper::new(move |x: i32| {
176        counter += 1;
177        x * counter
178    });
179    let once_mapper = mapper.into_box_once();
180    println!("  BoxMapper->BoxMapperOnce: {}", once_mapper.apply_once(5)); // 5 * 1 = 5
181
182    // RcMapper can use to_box_once() to preserve original
183    let mut counter = 0;
184    let rc_mapper = RcMapper::new(move |x: i32| {
185        counter += 1;
186        x * counter
187    });
188    let once_mapper = rc_mapper.to_box_once();
189    println!("  RcMapper->BoxMapperOnce: {}", once_mapper.apply_once(5)); // 5 * 1 = 5
190    println!(
191        "  Original RcMapper still works: {}",
192        rc_mapper.clone().apply(5)
193    ); // 5 * 2 = 10
194
195    println!("\n=== Demo Complete ===");
196}
Source§

impl<T, R> BoxMapper<T, R>
where T: 'static, R: Clone + 'static,

Source

pub fn constant(value: R) -> BoxMapper<T, R>

Creates a constant mapper

§Examples
use prism3_function::{BoxMapper, Mapper};

let mut constant = BoxMapper::constant("hello");
assert_eq!(constant.apply(123), "hello");

Trait Implementations§

Source§

impl<T, R> Mapper<T, R> for BoxMapper<T, R>

Source§

fn apply(&mut self, input: T) -> R

Applies the mapping to the input value to produce an output value Read more
Source§

fn into_box(self) -> BoxMapper<T, R>
where T: 'static, R: 'static,

Converts to BoxMapper Read more
Source§

fn into_rc(self) -> RcMapper<T, R>
where T: 'static, R: 'static,

Converts to RcMapper Read more
Source§

fn into_fn(self) -> impl FnMut(T) -> R
where T: 'static, R: 'static,

Converts to a closure implementing FnMut(T) -> R Read more
Source§

fn into_arc(self) -> ArcMapper<T, R>
where Self: Sized + Send + 'static, T: Send + Sync + 'static, R: Send + 'static,

Converts to ArcMapper Read more
Source§

impl<T, R> MapperOnce<T, R> for BoxMapper<T, R>
where T: 'static, R: 'static,

Source§

fn apply_once(self, input: T) -> R

Applies the mapping to the input value, consuming both self and input Read more
Source§

fn into_box_once(self) -> BoxMapperOnce<T, R>
where Self: Sized + 'static,

Converts to BoxMapperOnce Read more
Source§

fn into_fn_once(self) -> impl FnOnce(T) -> R
where Self: Sized + 'static,

Converts mapper to a closure Read more

Auto Trait Implementations§

§

impl<T, R> Freeze for BoxMapper<T, R>

§

impl<T, R> !RefUnwindSafe for BoxMapper<T, R>

§

impl<T, R> !Send for BoxMapper<T, R>

§

impl<T, R> !Sync for BoxMapper<T, R>

§

impl<T, R> Unpin for BoxMapper<T, R>

§

impl<T, R> !UnwindSafe for BoxMapper<T, R>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.