pub struct ArcMutator<T> { /* private fields */ }Expand description
ArcMutator struct
A mutator implementation based on Arc<Mutex<dyn FnMut(&mut T) + Send>>
for thread-safe shared ownership scenarios. This type allows the mutator
to be safely shared and used across multiple threads.
§Features
- Shared Ownership: Cloneable via
Arc, multiple owners allowed - Thread-Safe: Implements
Send + Sync, safe for concurrent use - Interior Mutability: Uses
Mutexfor safe concurrent mutations - Mutable State: Can modify captured environment via
FnMut - Chainable: Method chaining via
&self(non-consuming)
§Use Cases
Choose ArcMutator when:
- The mutator needs to be shared across multiple threads
- Concurrent task processing (e.g., thread pools)
- Thread safety is required (Send + Sync)
§Examples
use prism3_function::{Mutator, ArcMutator};
let mutator = ArcMutator::new(|x: &mut i32| *x *= 2);
let clone = mutator.clone();
let mut value = 5;
let mut m = mutator;
m.mutate(&mut value);
assert_eq!(value, 10);§Author
Haixing Hu
Implementations§
Source§impl<T> ArcMutator<T>where
T: Send + 'static,
impl<T> ArcMutator<T>where
T: Send + 'static,
Sourcepub fn new<F>(f: F) -> Self
pub fn new<F>(f: F) -> Self
Creates a new ArcMutator
§Parameters
f- The closure to wrap
§Returns
Returns a new ArcMutator<T> instance
§Examples
use prism3_function::{Mutator, ArcMutator};
let mutator = ArcMutator::new(|x: &mut i32| *x += 1);
let mut value = 5;
let mut m = mutator;
m.mutate(&mut value);
assert_eq!(value, 6);Examples found in repository?
20fn main() {
21 println!("=== Mutator Demo ===\n");
22
23 // ========================================================================
24 // Example 1: BoxMutator Basic Usage
25 // ========================================================================
26 println!("Example 1: BoxMutator Basic Usage");
27 println!("{}", "-".repeat(50));
28
29 let mut mutator = BoxMutator::new(|x: &mut i32| {
30 *x *= 2;
31 });
32 let mut value = 5;
33 println!("Initial value: {}", value);
34 mutator.mutate(&mut value);
35 println!("After BoxMutator execution: {}\n", value);
36
37 // ========================================================================
38 // Example 2: BoxMutator Method Chaining
39 // ========================================================================
40 println!("Example 2: BoxMutator Method Chaining");
41 println!("{}", "-".repeat(50));
42
43 let mut chained = BoxMutator::new(|x: &mut i32| {
44 *x *= 2; // multiply by 2
45 })
46 .and_then(|x: &mut i32| {
47 *x += 10; // add 10
48 })
49 .and_then(|x: &mut i32| {
50 *x = *x * *x; // square
51 });
52
53 let mut value = 5;
54 println!("Initial value: {}", value);
55 chained.mutate(&mut value);
56 println!("Result: {} (5 * 2 + 10 = 20, 20 * 20 = 400)\n", value);
57
58 // ========================================================================
59 // Example 3: Closure Extension Methods
60 // ========================================================================
61 println!("Example 3: Direct Use of Closure Extension Methods");
62 println!("{}", "-".repeat(50));
63
64 let mut closure_chain = (|x: &mut i32| *x *= 2).and_then(|x: &mut i32| *x += 10);
65
66 let mut value = 5;
67 println!("Initial value: {}", value);
68 closure_chain.mutate(&mut value);
69 println!("Result: {} (5 * 2 + 10 = 20)\n", value);
70
71 // ========================================================================
72 // Example 4: BoxMutator Factory Methods
73 // ========================================================================
74 println!("Example 4: BoxMutator Factory Methods");
75 println!("{}", "-".repeat(50));
76
77 // noop
78 let mut noop = BoxMutator::<i32>::noop();
79 let mut value = 42;
80 println!("Before noop: {}", value);
81 noop.mutate(&mut value);
82 println!("After noop: {} (unchanged)\n", value);
83
84 // ========================================================================
85 // Example 5: Conditional Mutator
86 // ========================================================================
87 println!("Example 5: Conditional Mutator");
88 println!("{}", "-".repeat(50));
89
90 // when (conditional execution)
91 let mut increment_if_positive = BoxMutator::new(|x: &mut i32| *x += 1).when(|x: &i32| *x > 0);
92
93 let mut positive = 5;
94 let mut negative = -5;
95 println!(
96 "Before when - positive: {}, negative: {}",
97 positive, negative
98 );
99 increment_if_positive.mutate(&mut positive);
100 increment_if_positive.mutate(&mut negative);
101 println!(
102 "After when - positive: {}, negative: {}\n",
103 positive, negative
104 );
105
106 // when().or_else() (conditional branching)
107 let mut adjust = BoxMutator::new(|x: &mut i32| *x *= 2)
108 .when(|x: &i32| *x > 0)
109 .or_else(|x: &mut i32| *x = -*x);
110
111 let mut positive = 10;
112 let mut negative = -10;
113 println!(
114 "Before when().or_else() - positive: {}, negative: {}",
115 positive, negative
116 );
117 adjust.mutate(&mut positive);
118 adjust.mutate(&mut negative);
119 println!(
120 "After when().or_else() - positive: {}, negative: {}\n",
121 positive, negative
122 );
123
124 // ========================================================================
125 // Example 6: ArcMutator - Multi-threaded Sharing
126 // ========================================================================
127 println!("Example 6: ArcMutator - Multi-threaded Sharing");
128 println!("{}", "-".repeat(50));
129
130 let shared = ArcMutator::new(|x: &mut i32| *x *= 2);
131
132 // Clone for another thread
133 let shared_clone = shared.clone();
134 let handle = thread::spawn(move || {
135 let mut value = 5;
136 let mut mutator = shared_clone;
137 mutator.mutate(&mut value);
138 println!("In thread: 5 * 2 = {}", value);
139 value
140 });
141
142 // Use in main thread
143 let mut value = 3;
144 let mut mutator = shared;
145 mutator.mutate(&mut value);
146 println!("Main thread: 3 * 2 = {}", value);
147
148 let thread_result = handle.join().unwrap();
149 println!("Thread result: {}\n", thread_result);
150
151 // ========================================================================
152 // Example 7: ArcMutator Composition (without consuming original mutator)
153 // ========================================================================
154 println!("Example 7: ArcMutator Composition (borrowing &self)");
155 println!("{}", "-".repeat(50));
156
157 let double = ArcMutator::new(|x: &mut i32| *x *= 2);
158 let add_ten = ArcMutator::new(|x: &mut i32| *x += 10);
159
160 // Composition doesn't consume the original mutator
161 let pipeline1 = double.and_then(&add_ten);
162 let pipeline2 = add_ten.and_then(&double);
163
164 let mut value1 = 5;
165 let mut p1 = pipeline1;
166 p1.mutate(&mut value1);
167 println!("pipeline1 (double then add): 5 -> {}", value1);
168
169 let mut value2 = 5;
170 let mut p2 = pipeline2;
171 p2.mutate(&mut value2);
172 println!("pipeline2 (add then double): 5 -> {}", value2);
173
174 // double and add_ten are still available
175 let mut value3 = 10;
176 let mut d = double;
177 d.mutate(&mut value3);
178 println!("Original double still available: 10 -> {}\n", value3);
179
180 // ========================================================================
181 // Example 8: RcMutator - Single-threaded Sharing
182 // ========================================================================
183 println!("Example 8: RcMutator - Single-threaded Sharing");
184 println!("{}", "-".repeat(50));
185
186 let rc_mutator = RcMutator::new(|x: &mut i32| *x *= 2);
187
188 // Clone multiple copies
189 let clone1 = rc_mutator.clone();
190 let clone2 = rc_mutator.clone();
191
192 let mut value1 = 5;
193 let mut c1 = clone1;
194 c1.mutate(&mut value1);
195 println!("clone1: 5 -> {}", value1);
196
197 let mut value2 = 3;
198 let mut c2 = clone2;
199 c2.mutate(&mut value2);
200 println!("clone2: 3 -> {}", value2);
201
202 let mut value3 = 7;
203 let mut c3 = rc_mutator;
204 c3.mutate(&mut value3);
205 println!("Original: 7 -> {}\n", value3);
206
207 // ========================================================================
208 // Example 9: RcMutator Composition (borrowing &self)
209 // ========================================================================
210 println!("Example 9: RcMutator Composition (borrowing &self)");
211 println!("{}", "-".repeat(50));
212
213 let double = RcMutator::new(|x: &mut i32| *x *= 2);
214 let add_ten = RcMutator::new(|x: &mut i32| *x += 10);
215
216 let pipeline1 = double.and_then(&add_ten);
217 let pipeline2 = add_ten.and_then(&double);
218
219 let mut value1 = 5;
220 let mut p1 = pipeline1;
221 p1.mutate(&mut value1);
222 println!("pipeline1 (double then add): 5 -> {}", value1);
223
224 let mut value2 = 5;
225 let mut p2 = pipeline2;
226 p2.mutate(&mut value2);
227 println!("pipeline2 (add then double): 5 -> {}\n", value2);
228
229 // ========================================================================
230 // Example 10: Unified Mutator trait
231 // ========================================================================
232 println!("Example 10: Unified Mutator trait");
233 println!("{}", "-".repeat(50));
234
235 fn apply_to_all<M: Mutator<i32>>(mutator: &mut M, values: &mut [i32]) {
236 for value in values.iter_mut() {
237 mutator.mutate(value);
238 }
239 }
240
241 let mut values1 = vec![1, 2, 3, 4, 5];
242 let mut box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
243 println!("Using BoxMutator: {:?}", values1);
244 apply_to_all(&mut box_mut, &mut values1);
245 println!("Result: {:?}", values1);
246
247 let mut values2 = vec![1, 2, 3, 4, 5];
248 let mut arc_mut = ArcMutator::new(|x: &mut i32| *x *= 2);
249 println!("Using ArcMutator: {:?}", values2);
250 apply_to_all(&mut arc_mut, &mut values2);
251 println!("Result: {:?}", values2);
252
253 let mut values3 = vec![1, 2, 3, 4, 5];
254 let mut rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
255 println!("Using RcMutator: {:?}", values3);
256 apply_to_all(&mut rc_mut, &mut values3);
257 println!("Result: {:?}", values3);
258
259 let mut values4 = vec![1, 2, 3, 4, 5];
260 let mut closure = |x: &mut i32| *x *= 2;
261 println!("Using closure: {:?}", values4);
262 apply_to_all(&mut closure, &mut values4);
263 println!("Result: {:?}\n", values4);
264
265 // ========================================================================
266 // Example 11: Complex Data Processing Pipeline
267 // ========================================================================
268 println!("Example 11: Complex Data Processing Pipeline");
269 println!("{}", "-".repeat(50));
270
271 let mut pipeline = BoxMutator::new(|x: &mut i32| {
272 // Validation: clamp to 0-100
273 *x = (*x).clamp(0, 100);
274 })
275 .and_then(|x: &mut i32| {
276 // Normalization: scale to 0-10
277 *x /= 10;
278 })
279 .and_then(|x: &mut i32| {
280 // Transformation: square
281 *x = *x * *x;
282 });
283
284 let mut value1 = -50;
285 pipeline.mutate(&mut value1);
286 println!("-50 -> {}", value1);
287
288 let mut value2 = 200;
289 pipeline.mutate(&mut value2);
290 println!("200 -> {}", value2);
291
292 let mut value3 = 30;
293 pipeline.mutate(&mut value3);
294 println!("30 -> {}\n", value3);
295
296 // ========================================================================
297 // Example 12: String Processing
298 // ========================================================================
299 println!("Example 12: String Processing");
300 println!("{}", "-".repeat(50));
301
302 let mut string_processor = BoxMutator::new(|s: &mut String| s.retain(|c| !c.is_whitespace()))
303 .and_then(|s: &mut String| *s = s.to_lowercase())
304 .and_then(|s: &mut String| s.push_str("!!!"));
305
306 let mut text = String::from("Hello World");
307 println!("Original: {}", text);
308 string_processor.mutate(&mut text);
309 println!("After processing: {}\n", text);
310
311 // ========================================================================
312 // Example 13: Type Conversion
313 // ========================================================================
314 println!("Example 13: Type Conversion");
315 println!("{}", "-".repeat(50));
316
317 // Closure -> BoxMutator
318 let closure = |x: &mut i32| *x *= 2;
319 let mut box_mut = closure.into_box();
320 let mut value = 5;
321 box_mut.mutate(&mut value);
322 println!("Closure -> BoxMutator: 5 -> {}", value);
323
324 // Closure -> RcMutator
325 let closure = |x: &mut i32| *x *= 2;
326 let mut rc_mut = closure.into_rc();
327 let mut value = 5;
328 rc_mut.mutate(&mut value);
329 println!("Closure -> RcMutator: 5 -> {}", value);
330
331 // Closure -> ArcMutator
332 let closure = |x: &mut i32| *x *= 2;
333 let mut arc_mut = closure.into_arc();
334 let mut value = 5;
335 arc_mut.mutate(&mut value);
336 println!("Closure -> ArcMutator: 5 -> {}", value);
337
338 // BoxMutator -> RcMutator
339 let box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
340 let mut rc_mut = box_mut.into_rc();
341 let mut value = 5;
342 rc_mut.mutate(&mut value);
343 println!("BoxMutator -> RcMutator: 5 -> {}", value);
344
345 // RcMutator -> BoxMutator
346 let rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
347 let mut box_mut = rc_mut.into_box();
348 let mut value = 5;
349 box_mut.mutate(&mut value);
350 println!("RcMutator -> BoxMutator: 5 -> {}\n", value);
351
352 // ========================================================================
353 // Example 14: Custom Types
354 // ========================================================================
355 println!("Example 14: Custom Types");
356 println!("{}", "-".repeat(50));
357
358 #[derive(Debug, Clone)]
359 struct Point {
360 x: i32,
361 y: i32,
362 }
363
364 let mut processor = BoxMutator::new(|p: &mut Point| p.x *= 2)
365 .and_then(|p: &mut Point| p.y *= 2)
366 .and_then(|p: &mut Point| p.x += p.y);
367
368 let mut point = Point { x: 3, y: 4 };
369 println!("Original point: {:?}", point);
370 processor.mutate(&mut point);
371 println!("After processing: {:?}\n", point);
372
373 println!("=== All Examples Completed ===");
374}Sourcepub fn and_then(&self, next: &ArcMutator<T>) -> ArcMutator<T>
pub fn and_then(&self, next: &ArcMutator<T>) -> ArcMutator<T>
Chains another ArcMutator in sequence
Returns a new mutator that first executes the current operation, then executes the next operation. Borrows &self, does not consume the original mutator.
§Parameters
next- The mutator to execute after the current operation
§Returns
Returns a new composed ArcMutator<T>
§Examples
use prism3_function::{Mutator, ArcMutator};
let first = ArcMutator::new(|x: &mut i32| *x *= 2);
let second = ArcMutator::new(|x: &mut i32| *x += 10);
let chained = first.and_then(&second);
// first and second are still usable
let mut value = 5;
let mut m = chained;
m.mutate(&mut value);
assert_eq!(value, 20); // (5 * 2) + 10Examples found in repository?
20fn main() {
21 println!("=== Mutator Demo ===\n");
22
23 // ========================================================================
24 // Example 1: BoxMutator Basic Usage
25 // ========================================================================
26 println!("Example 1: BoxMutator Basic Usage");
27 println!("{}", "-".repeat(50));
28
29 let mut mutator = BoxMutator::new(|x: &mut i32| {
30 *x *= 2;
31 });
32 let mut value = 5;
33 println!("Initial value: {}", value);
34 mutator.mutate(&mut value);
35 println!("After BoxMutator execution: {}\n", value);
36
37 // ========================================================================
38 // Example 2: BoxMutator Method Chaining
39 // ========================================================================
40 println!("Example 2: BoxMutator Method Chaining");
41 println!("{}", "-".repeat(50));
42
43 let mut chained = BoxMutator::new(|x: &mut i32| {
44 *x *= 2; // multiply by 2
45 })
46 .and_then(|x: &mut i32| {
47 *x += 10; // add 10
48 })
49 .and_then(|x: &mut i32| {
50 *x = *x * *x; // square
51 });
52
53 let mut value = 5;
54 println!("Initial value: {}", value);
55 chained.mutate(&mut value);
56 println!("Result: {} (5 * 2 + 10 = 20, 20 * 20 = 400)\n", value);
57
58 // ========================================================================
59 // Example 3: Closure Extension Methods
60 // ========================================================================
61 println!("Example 3: Direct Use of Closure Extension Methods");
62 println!("{}", "-".repeat(50));
63
64 let mut closure_chain = (|x: &mut i32| *x *= 2).and_then(|x: &mut i32| *x += 10);
65
66 let mut value = 5;
67 println!("Initial value: {}", value);
68 closure_chain.mutate(&mut value);
69 println!("Result: {} (5 * 2 + 10 = 20)\n", value);
70
71 // ========================================================================
72 // Example 4: BoxMutator Factory Methods
73 // ========================================================================
74 println!("Example 4: BoxMutator Factory Methods");
75 println!("{}", "-".repeat(50));
76
77 // noop
78 let mut noop = BoxMutator::<i32>::noop();
79 let mut value = 42;
80 println!("Before noop: {}", value);
81 noop.mutate(&mut value);
82 println!("After noop: {} (unchanged)\n", value);
83
84 // ========================================================================
85 // Example 5: Conditional Mutator
86 // ========================================================================
87 println!("Example 5: Conditional Mutator");
88 println!("{}", "-".repeat(50));
89
90 // when (conditional execution)
91 let mut increment_if_positive = BoxMutator::new(|x: &mut i32| *x += 1).when(|x: &i32| *x > 0);
92
93 let mut positive = 5;
94 let mut negative = -5;
95 println!(
96 "Before when - positive: {}, negative: {}",
97 positive, negative
98 );
99 increment_if_positive.mutate(&mut positive);
100 increment_if_positive.mutate(&mut negative);
101 println!(
102 "After when - positive: {}, negative: {}\n",
103 positive, negative
104 );
105
106 // when().or_else() (conditional branching)
107 let mut adjust = BoxMutator::new(|x: &mut i32| *x *= 2)
108 .when(|x: &i32| *x > 0)
109 .or_else(|x: &mut i32| *x = -*x);
110
111 let mut positive = 10;
112 let mut negative = -10;
113 println!(
114 "Before when().or_else() - positive: {}, negative: {}",
115 positive, negative
116 );
117 adjust.mutate(&mut positive);
118 adjust.mutate(&mut negative);
119 println!(
120 "After when().or_else() - positive: {}, negative: {}\n",
121 positive, negative
122 );
123
124 // ========================================================================
125 // Example 6: ArcMutator - Multi-threaded Sharing
126 // ========================================================================
127 println!("Example 6: ArcMutator - Multi-threaded Sharing");
128 println!("{}", "-".repeat(50));
129
130 let shared = ArcMutator::new(|x: &mut i32| *x *= 2);
131
132 // Clone for another thread
133 let shared_clone = shared.clone();
134 let handle = thread::spawn(move || {
135 let mut value = 5;
136 let mut mutator = shared_clone;
137 mutator.mutate(&mut value);
138 println!("In thread: 5 * 2 = {}", value);
139 value
140 });
141
142 // Use in main thread
143 let mut value = 3;
144 let mut mutator = shared;
145 mutator.mutate(&mut value);
146 println!("Main thread: 3 * 2 = {}", value);
147
148 let thread_result = handle.join().unwrap();
149 println!("Thread result: {}\n", thread_result);
150
151 // ========================================================================
152 // Example 7: ArcMutator Composition (without consuming original mutator)
153 // ========================================================================
154 println!("Example 7: ArcMutator Composition (borrowing &self)");
155 println!("{}", "-".repeat(50));
156
157 let double = ArcMutator::new(|x: &mut i32| *x *= 2);
158 let add_ten = ArcMutator::new(|x: &mut i32| *x += 10);
159
160 // Composition doesn't consume the original mutator
161 let pipeline1 = double.and_then(&add_ten);
162 let pipeline2 = add_ten.and_then(&double);
163
164 let mut value1 = 5;
165 let mut p1 = pipeline1;
166 p1.mutate(&mut value1);
167 println!("pipeline1 (double then add): 5 -> {}", value1);
168
169 let mut value2 = 5;
170 let mut p2 = pipeline2;
171 p2.mutate(&mut value2);
172 println!("pipeline2 (add then double): 5 -> {}", value2);
173
174 // double and add_ten are still available
175 let mut value3 = 10;
176 let mut d = double;
177 d.mutate(&mut value3);
178 println!("Original double still available: 10 -> {}\n", value3);
179
180 // ========================================================================
181 // Example 8: RcMutator - Single-threaded Sharing
182 // ========================================================================
183 println!("Example 8: RcMutator - Single-threaded Sharing");
184 println!("{}", "-".repeat(50));
185
186 let rc_mutator = RcMutator::new(|x: &mut i32| *x *= 2);
187
188 // Clone multiple copies
189 let clone1 = rc_mutator.clone();
190 let clone2 = rc_mutator.clone();
191
192 let mut value1 = 5;
193 let mut c1 = clone1;
194 c1.mutate(&mut value1);
195 println!("clone1: 5 -> {}", value1);
196
197 let mut value2 = 3;
198 let mut c2 = clone2;
199 c2.mutate(&mut value2);
200 println!("clone2: 3 -> {}", value2);
201
202 let mut value3 = 7;
203 let mut c3 = rc_mutator;
204 c3.mutate(&mut value3);
205 println!("Original: 7 -> {}\n", value3);
206
207 // ========================================================================
208 // Example 9: RcMutator Composition (borrowing &self)
209 // ========================================================================
210 println!("Example 9: RcMutator Composition (borrowing &self)");
211 println!("{}", "-".repeat(50));
212
213 let double = RcMutator::new(|x: &mut i32| *x *= 2);
214 let add_ten = RcMutator::new(|x: &mut i32| *x += 10);
215
216 let pipeline1 = double.and_then(&add_ten);
217 let pipeline2 = add_ten.and_then(&double);
218
219 let mut value1 = 5;
220 let mut p1 = pipeline1;
221 p1.mutate(&mut value1);
222 println!("pipeline1 (double then add): 5 -> {}", value1);
223
224 let mut value2 = 5;
225 let mut p2 = pipeline2;
226 p2.mutate(&mut value2);
227 println!("pipeline2 (add then double): 5 -> {}\n", value2);
228
229 // ========================================================================
230 // Example 10: Unified Mutator trait
231 // ========================================================================
232 println!("Example 10: Unified Mutator trait");
233 println!("{}", "-".repeat(50));
234
235 fn apply_to_all<M: Mutator<i32>>(mutator: &mut M, values: &mut [i32]) {
236 for value in values.iter_mut() {
237 mutator.mutate(value);
238 }
239 }
240
241 let mut values1 = vec![1, 2, 3, 4, 5];
242 let mut box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
243 println!("Using BoxMutator: {:?}", values1);
244 apply_to_all(&mut box_mut, &mut values1);
245 println!("Result: {:?}", values1);
246
247 let mut values2 = vec![1, 2, 3, 4, 5];
248 let mut arc_mut = ArcMutator::new(|x: &mut i32| *x *= 2);
249 println!("Using ArcMutator: {:?}", values2);
250 apply_to_all(&mut arc_mut, &mut values2);
251 println!("Result: {:?}", values2);
252
253 let mut values3 = vec![1, 2, 3, 4, 5];
254 let mut rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
255 println!("Using RcMutator: {:?}", values3);
256 apply_to_all(&mut rc_mut, &mut values3);
257 println!("Result: {:?}", values3);
258
259 let mut values4 = vec![1, 2, 3, 4, 5];
260 let mut closure = |x: &mut i32| *x *= 2;
261 println!("Using closure: {:?}", values4);
262 apply_to_all(&mut closure, &mut values4);
263 println!("Result: {:?}\n", values4);
264
265 // ========================================================================
266 // Example 11: Complex Data Processing Pipeline
267 // ========================================================================
268 println!("Example 11: Complex Data Processing Pipeline");
269 println!("{}", "-".repeat(50));
270
271 let mut pipeline = BoxMutator::new(|x: &mut i32| {
272 // Validation: clamp to 0-100
273 *x = (*x).clamp(0, 100);
274 })
275 .and_then(|x: &mut i32| {
276 // Normalization: scale to 0-10
277 *x /= 10;
278 })
279 .and_then(|x: &mut i32| {
280 // Transformation: square
281 *x = *x * *x;
282 });
283
284 let mut value1 = -50;
285 pipeline.mutate(&mut value1);
286 println!("-50 -> {}", value1);
287
288 let mut value2 = 200;
289 pipeline.mutate(&mut value2);
290 println!("200 -> {}", value2);
291
292 let mut value3 = 30;
293 pipeline.mutate(&mut value3);
294 println!("30 -> {}\n", value3);
295
296 // ========================================================================
297 // Example 12: String Processing
298 // ========================================================================
299 println!("Example 12: String Processing");
300 println!("{}", "-".repeat(50));
301
302 let mut string_processor = BoxMutator::new(|s: &mut String| s.retain(|c| !c.is_whitespace()))
303 .and_then(|s: &mut String| *s = s.to_lowercase())
304 .and_then(|s: &mut String| s.push_str("!!!"));
305
306 let mut text = String::from("Hello World");
307 println!("Original: {}", text);
308 string_processor.mutate(&mut text);
309 println!("After processing: {}\n", text);
310
311 // ========================================================================
312 // Example 13: Type Conversion
313 // ========================================================================
314 println!("Example 13: Type Conversion");
315 println!("{}", "-".repeat(50));
316
317 // Closure -> BoxMutator
318 let closure = |x: &mut i32| *x *= 2;
319 let mut box_mut = closure.into_box();
320 let mut value = 5;
321 box_mut.mutate(&mut value);
322 println!("Closure -> BoxMutator: 5 -> {}", value);
323
324 // Closure -> RcMutator
325 let closure = |x: &mut i32| *x *= 2;
326 let mut rc_mut = closure.into_rc();
327 let mut value = 5;
328 rc_mut.mutate(&mut value);
329 println!("Closure -> RcMutator: 5 -> {}", value);
330
331 // Closure -> ArcMutator
332 let closure = |x: &mut i32| *x *= 2;
333 let mut arc_mut = closure.into_arc();
334 let mut value = 5;
335 arc_mut.mutate(&mut value);
336 println!("Closure -> ArcMutator: 5 -> {}", value);
337
338 // BoxMutator -> RcMutator
339 let box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
340 let mut rc_mut = box_mut.into_rc();
341 let mut value = 5;
342 rc_mut.mutate(&mut value);
343 println!("BoxMutator -> RcMutator: 5 -> {}", value);
344
345 // RcMutator -> BoxMutator
346 let rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
347 let mut box_mut = rc_mut.into_box();
348 let mut value = 5;
349 box_mut.mutate(&mut value);
350 println!("RcMutator -> BoxMutator: 5 -> {}\n", value);
351
352 // ========================================================================
353 // Example 14: Custom Types
354 // ========================================================================
355 println!("Example 14: Custom Types");
356 println!("{}", "-".repeat(50));
357
358 #[derive(Debug, Clone)]
359 struct Point {
360 x: i32,
361 y: i32,
362 }
363
364 let mut processor = BoxMutator::new(|p: &mut Point| p.x *= 2)
365 .and_then(|p: &mut Point| p.y *= 2)
366 .and_then(|p: &mut Point| p.x += p.y);
367
368 let mut point = Point { x: 3, y: 4 };
369 println!("Original point: {:?}", point);
370 processor.mutate(&mut point);
371 println!("After processing: {:?}\n", point);
372
373 println!("=== All Examples Completed ===");
374}Sourcepub fn when<P>(&self, predicate: P) -> ArcConditionalMutator<T>
pub fn when<P>(&self, predicate: P) -> ArcConditionalMutator<T>
Creates a conditional mutator (thread-safe version)
Returns a mutator that only executes when a predicate is 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). Must beSend + Sync, can be:- A closure:
|x: &T| -> bool(requiresSend + Sync) - A function pointer:
fn(&T) -> bool - An
ArcPredicate<T> - Any type implementing
Predicate<T> + Send + Sync
- A closure:
§Returns
Returns ArcConditionalMutator<T>
§Examples
use prism3_function::{Mutator, ArcMutator};
let mutator = ArcMutator::new(|x: &mut i32| *x *= 2);
let conditional = mutator.when(|x: &i32| *x > 0);
let conditional_clone = conditional.clone();
let mut positive = 5;
let mut m = conditional;
m.mutate(&mut positive);
assert_eq!(positive, 10);Trait Implementations§
Source§impl<T> Clone for ArcMutator<T>
impl<T> Clone for ArcMutator<T>
Source§impl<T> Mutator<T> for ArcMutator<T>
impl<T> Mutator<T> for ArcMutator<T>
Source§fn into_box(self) -> BoxMutator<T>where
T: 'static,
fn into_box(self) -> BoxMutator<T>where
T: 'static,
BoxMutator<T>. Read moreSource§fn into_rc(self) -> RcMutator<T>where
T: 'static,
fn into_rc(self) -> RcMutator<T>where
T: 'static,
RcMutator<T>. Read moreSource§fn into_arc(self) -> ArcMutator<T>where
T: Send + 'static,
fn into_arc(self) -> ArcMutator<T>where
T: Send + 'static,
ArcMutator<T>. Read moreSource§fn into_fn(self) -> impl FnMut(&mut T)where
Self: Sized + 'static,
T: 'static,
fn into_fn(self) -> impl FnMut(&mut T)where
Self: Sized + 'static,
T: 'static,
FnMut(&mut T) closure. Read moreSource§fn to_box(&self) -> BoxMutator<T>where
Self: Sized + 'static,
T: 'static,
fn to_box(&self) -> BoxMutator<T>where
Self: Sized + 'static,
T: 'static,
Source§fn to_arc(&self) -> ArcMutator<T>
fn to_arc(&self) -> ArcMutator<T>
Source§impl<T> MutatorOnce<T> for ArcMutator<T>where
T: Send + 'static,
impl<T> MutatorOnce<T> for ArcMutator<T>where
T: Send + 'static,
Source§fn mutate_once(self, value: &mut T)
fn mutate_once(self, value: &mut T)
Performs the one-time mutation operation
Consumes self and executes the mutation operation on the given mutable reference. This is a one-time operation that cannot be called again.
§Parameters
value- A mutable reference to the value to be mutated
§Examples
use prism3_function::{Mutator, MutatorOnce, ArcMutator};
let mutator = ArcMutator::new(|x: &mut i32| *x *= 2);
let mut value = 5;
mutator.mutate_once(&mut value);
assert_eq!(value, 10);Source§fn into_box_once(self) -> BoxMutatorOnce<T>where
Self: Sized + 'static,
T: 'static,
fn into_box_once(self) -> BoxMutatorOnce<T>where
Self: Sized + 'static,
T: 'static,
Converts to BoxMutatorOnce (consuming)
Consumes self and returns an owned BoxMutatorOnce<T>. The underlying
function is extracted from the Arc<Mutex<>> wrapper.
§Returns
Returns a BoxMutatorOnce<T> that forwards to the original mutator.
Source§fn into_fn_once(self) -> impl FnOnce(&mut T)where
Self: Sized + 'static,
T: 'static,
fn into_fn_once(self) -> impl FnOnce(&mut T)where
Self: Sized + 'static,
T: 'static,
Converts to a consuming closure FnOnce(&mut T)
Consumes self and returns a closure that, when invoked, calls the
mutation operation.
§Returns
A closure implementing FnOnce(&mut T) which forwards to the original
mutator.
Source§fn to_box_once(&self) -> BoxMutatorOnce<T>where
Self: Sized + 'static,
T: 'static,
fn to_box_once(&self) -> BoxMutatorOnce<T>where
Self: Sized + 'static,
T: 'static,
Non-consuming adapter to BoxMutatorOnce
Creates a BoxMutatorOnce<T> that does not consume self. This method
clones the underlying Arc reference and creates a new boxed mutator.
§Returns
A BoxMutatorOnce<T> that forwards to a clone of self.
Source§fn to_fn_once(&self) -> impl FnOnce(&mut T)where
Self: Sized + 'static,
T: 'static,
fn to_fn_once(&self) -> impl FnOnce(&mut T)where
Self: Sized + 'static,
T: 'static,
Non-consuming adapter to a callable FnOnce(&mut T)
Returns a closure that does not consume self. This method clones the
underlying Arc reference for the captured closure.
§Returns
A closure implementing FnOnce(&mut T) which forwards to a clone of
the original mutator.