pub trait Mutator<T> {
// Required method
fn mutate(&mut self, value: &mut T);
// Provided methods
fn into_box(self) -> BoxMutator<T>
where Self: Sized + 'static,
T: 'static { ... }
fn into_rc(self) -> RcMutator<T>
where Self: Sized + 'static,
T: 'static { ... }
fn into_arc(self) -> ArcMutator<T>
where Self: Sized + Send + 'static,
T: Send + 'static { ... }
fn into_fn(self) -> impl FnMut(&mut T)
where Self: Sized + 'static,
T: 'static { ... }
fn to_box(&self) -> BoxMutator<T>
where Self: Sized + Clone + 'static,
T: 'static { ... }
fn to_rc(&self) -> RcMutator<T>
where Self: Sized + Clone + 'static,
T: 'static { ... }
fn to_arc(&self) -> ArcMutator<T>
where Self: Sized + Clone + Send + 'static,
T: Send + 'static { ... }
fn to_fn(&self) -> impl FnMut(&mut T)
where Self: Sized + Clone + 'static,
T: 'static { ... }
}Expand description
Mutator trait - Unified mutator interface
Defines the core behavior of all mutator types. Performs operations that accept a mutable reference and modify the input value (not just side effects).
This trait is automatically implemented by:
- All closures implementing
FnMut(&mut T) BoxMutator<T>,ArcMutator<T>, andRcMutator<T>
§Design Rationale
The trait provides a unified abstraction over different ownership models,
allowing generic code to work with any mutator type. Type conversion
methods (into_box, into_arc, into_rc) enable flexible ownership
transitions based on usage requirements.
§Features
- Unified Interface: All mutator types share the same
mutatemethod signature - Automatic Implementation: Closures automatically implement this trait with zero overhead
- Type Conversions: Easy conversion between ownership models
- Generic Programming: Write functions that work with any mutator type
§Examples
§Generic Mutator Function
use prism3_function::{Mutator, BoxMutator, ArcMutator};
fn apply_mutator<M: Mutator<i32>>(
mutator: &mut M,
value: i32
) -> i32 {
let mut val = value;
mutator.mutate(&mut val);
val
}
// Works with any mutator type
let mut box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
assert_eq!(apply_mutator(&mut box_mut, 5), 10);
let mut arc_mut = ArcMutator::new(|x: &mut i32| *x *= 2);
assert_eq!(apply_mutator(&mut arc_mut, 5), 10);
let mut closure = |x: &mut i32| *x *= 2;
assert_eq!(apply_mutator(&mut closure, 5), 10);§Type Conversion
use prism3_function::Mutator;
let closure = |x: &mut i32| *x *= 2;
// Convert to different ownership models
let box_mutator = closure.into_box();
// let rc_mutator = closure.into_rc(); // closure moved
// let arc_mutator = closure.into_arc(); // closure moved§Author
Haixing Hu
Required Methods§
Sourcefn mutate(&mut self, value: &mut T)
fn mutate(&mut self, value: &mut T)
Performs the mutation operation
Executes an operation on the given mutable reference. The operation typically modifies the input value or produces side effects.
§Parameters
value- A mutable reference to the value to be mutated
§Examples
use prism3_function::{Mutator, BoxMutator};
let mut mutator = BoxMutator::new(|x: &mut i32| *x *= 2);
let mut value = 5;
mutator.mutate(&mut value);
assert_eq!(value, 10);Provided Methods§
Sourcefn into_box(self) -> BoxMutator<T>where
Self: Sized + 'static,
T: 'static,
fn into_box(self) -> BoxMutator<T>where
Self: Sized + 'static,
T: 'static,
Convert this mutator into a BoxMutator<T>.
This consuming conversion takes ownership of self and returns a
boxed implementation that forwards calls to the original mutator.
Types that can provide a more efficient conversion may override the
default implementation.
§Consumption
This method consumes the mutator: the original value will no longer
be available after the call. For cloneable mutators call .clone()
before converting if you need to retain the original instance.
§Returns
A BoxMutator<T> that forwards to the original mutator.
§Examples
use prism3_function::Mutator;
let closure = |x: &mut i32| *x *= 2;
let mut boxed = closure.into_box();
let mut value = 5;
boxed.mutate(&mut value);
assert_eq!(value, 10);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}Sourcefn into_rc(self) -> RcMutator<T>where
Self: Sized + 'static,
T: 'static,
fn into_rc(self) -> RcMutator<T>where
Self: Sized + 'static,
T: 'static,
Convert this mutator into an RcMutator<T>.
This consuming conversion takes ownership of self and returns an
Rc-backed mutator that forwards calls to the original. Override to
provide a more direct or efficient conversion when available.
§Consumption
This method consumes the mutator. If you need to keep the original instance, clone it prior to calling this method.
§Returns
An RcMutator<T> forwarding to the original mutator.
§Examples
use prism3_function::Mutator;
let closure = |x: &mut i32| *x *= 2;
let mut rc = closure.into_rc();
let mut value = 5;
rc.mutate(&mut value);
assert_eq!(value, 10);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}Sourcefn into_arc(self) -> ArcMutator<T>
fn into_arc(self) -> ArcMutator<T>
Convert this mutator into an ArcMutator<T>.
This consuming conversion takes ownership of self and returns an
Arc-wrapped, thread-safe mutator. Types may override the default
implementation to provide a more efficient conversion.
§Consumption
This method consumes the mutator. Clone the instance first if you need to retain the original for further use.
§Returns
An ArcMutator<T> that forwards to the original mutator.
§Examples
use prism3_function::Mutator;
let closure = |x: &mut i32| *x *= 2;
let mut arc = closure.into_arc();
let mut value = 5;
arc.mutate(&mut value);
assert_eq!(value, 10);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}Sourcefn 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,
Consume the mutator and return an FnMut(&mut T) closure.
The returned closure forwards calls to the original mutator and is
suitable for use with iterator adapters such as for_each.
§Consumption
This method consumes the mutator. The original instance will not be available after calling this method.
§Returns
A closure implementing FnMut(&mut T) which forwards to the
original mutator.
§Examples
use prism3_function::{Mutator, BoxMutator};
let mutator = BoxMutator::new(|x: &mut i32| *x *= 2);
let mut values = vec![1, 2, 3, 4, 5];
values.iter_mut().for_each(mutator.into_fn());
assert_eq!(values, vec![2, 4, 6, 8, 10]);Sourcefn to_box(&self) -> BoxMutator<T>
fn to_box(&self) -> BoxMutator<T>
Create a non-consuming BoxMutator<T> that forwards to self.
The default implementation clones self (requires Clone) and
returns a boxed mutator that calls the cloned instance. Override this
method if a more efficient conversion exists.
§Returns
A BoxMutator<T> that forwards to a clone of self.
Sourcefn to_rc(&self) -> RcMutator<T>
fn to_rc(&self) -> RcMutator<T>
Create a non-consuming RcMutator<T> that forwards to self.
The default implementation clones self (requires Clone) and
returns an Rc-backed mutator that forwards calls to the clone.
Override to provide a more direct or efficient conversion if needed.
§Returns
An RcMutator<T> that forwards to a clone of self.
Sourcefn to_arc(&self) -> ArcMutator<T>
fn to_arc(&self) -> ArcMutator<T>
Create a non-consuming ArcMutator<T> that forwards to self.
The default implementation clones self (requires Clone + Send) and
returns an Arc-wrapped mutator that forwards calls to the clone.
Override when a more efficient conversion is available.
§Returns
An ArcMutator<T> that forwards to a clone of self.
Sourcefn to_fn(&self) -> impl FnMut(&mut T)
fn to_fn(&self) -> impl FnMut(&mut T)
Create a boxed FnMut(&mut T) closure that forwards to self.
The default implementation clones self (requires Clone) and
returns a boxed closure that invokes the cloned instance. Override to
provide a more efficient conversion when possible.
§Returns
A closure implementing FnMut(&mut T) which forwards to the
original mutator.