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 + Syncrequirement) - Statefulness: Can modify internal state between calls
§Author
Haixing Hu
Implementations§
Source§impl<T, R> BoxMapper<T, R>where
T: 'static,
R: 'static,
impl<T, R> BoxMapper<T, R>where
T: 'static,
R: 'static,
Sourcepub fn new<F>(f: F) -> Selfwhere
F: FnMut(T) -> R + 'static,
pub fn new<F>(f: F) -> Selfwhere
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?
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}Sourcepub fn identity() -> BoxMapper<T, T>
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);Sourcepub fn and_then<S, F>(self, after: F) -> BoxMapper<T, S>where
S: 'static,
F: Mapper<R, S> + 'static,
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 mapperF- 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 implementsClone). 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>
- A closure:
§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) * 2Examples found in repository?
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}Sourcepub fn compose<S, F>(self, before: F) -> BoxMapper<S, R>where
S: 'static,
F: Mapper<S, T> + 'static,
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 mapperF- 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 implementsClone). 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>
- A closure:
§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) * 2Sourcepub fn when<P>(self, predicate: P) -> BoxConditionalMapper<T, R>where
P: Predicate<T> + 'static,
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 implementsClone). 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>
- A closure:
§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 + 1Examples found in repository?
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}