pub trait Mutator<T> {
// Required method
fn apply(&self, value: &mut T);
// Provided methods
fn into_box(self) -> BoxMutator<T>
where Self: Sized + 'static { ... }
fn into_rc(self) -> RcMutator<T>
where Self: Sized + 'static { ... }
fn into_arc(self) -> ArcMutator<T>
where Self: Sized + Send + Sync + 'static { ... }
fn into_fn(self) -> impl Fn(&mut T)
where Self: Sized + 'static { ... }
fn into_once(self) -> BoxMutatorOnce<T>
where Self: Sized + 'static { ... }
fn to_box(&self) -> BoxMutator<T>
where Self: Sized + Clone + 'static { ... }
fn to_rc(&self) -> RcMutator<T>
where Self: Sized + Clone + 'static { ... }
fn to_arc(&self) -> ArcMutator<T>
where Self: Sized + Clone + Send + Sync + 'static { ... }
fn to_fn(&self) -> impl Fn(&mut T)
where Self: Sized + Clone + 'static { ... }
fn to_once(&self) -> BoxMutatorOnce<T>
where Self: Sized + Clone + 'static { ... }
}Expand description
Mutator trait - Unified stateless mutator interface
Defines the core behavior of all stateless mutator types. Performs operations that accept a mutable reference and modify the input value without maintaining internal state.
This trait is automatically implemented by:
- All closures implementing
Fn(&mut T)(stateless) BoxMutator<T>,ArcMutator<T>, andRcMutator<T>
§Design Rationale
The trait provides a unified abstraction over different ownership models for
stateless operations. Unlike StatefulMutator which uses FnMut and can
modify its internal state, Mutator uses Fn for pure transformations.
§Features
- Stateless Operations: No internal state modification (
&selfnot&mut self) - Unified Interface: All mutator types share the same
mutatemethod signature - Automatic Implementation: Closures automatically implement this trait
- Type Conversions: Easy conversion between ownership models
- Generic Programming: Write functions that work with any mutator type
§Examples
§Generic Mutator Function
use qubit_function::{Mutator, BoxMutator, ArcMutator};
fn apply_mutator<M: Mutator<i32>>(
mutator: &mut M,
value: i32
) -> i32 {
let mut val = value;
mutator.apply(&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 qubit_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 apply(&self, value: &mut T)
fn apply(&self, value: &mut T)
Performs the stateless mutation operation
Executes an operation on the given mutable reference without modifying the mutator’s internal state. This is a pure transformation operation.
§Parameters
value- A mutable reference to the value to be mutated
§Examples
use qubit_function::{Mutator, BoxMutator};
let mutator = BoxMutator::new(|x: &mut i32| *x *= 2);
let mut value = 5;
mutator.apply(&mut value);
assert_eq!(value, 10);Provided Methods§
Sourcefn into_box(self) -> BoxMutator<T>where
Self: Sized + 'static,
fn into_box(self) -> BoxMutator<T>where
Self: Sized + '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 qubit_function::Mutator;
let closure = |x: &mut i32| *x *= 2;
let mut boxed = closure.into_box();
let mut value = 5;
boxed.apply(&mut value);
assert_eq!(value, 10);Examples found in repository?
26fn main() {
27 println!("=== Mutator Demo ===\n");
28
29 // ========================================================================
30 // Example 1: BoxMutator Basic Usage
31 // ========================================================================
32 println!("Example 1: BoxMutator Basic Usage");
33 println!("{}", "-".repeat(50));
34
35 let mutator = BoxMutator::new(|x: &mut i32| {
36 *x *= 2;
37 });
38 let mut value = 5;
39 println!("Initial value: {}", value);
40 mutator.apply(&mut value);
41 println!("After BoxMutator execution: {}\n", value);
42
43 // ========================================================================
44 // Example 2: BoxMutator Method Chaining
45 // ========================================================================
46 println!("Example 2: BoxMutator Method Chaining");
47 println!("{}", "-".repeat(50));
48
49 let chained = BoxMutator::new(|x: &mut i32| {
50 *x *= 2; // multiply by 2
51 })
52 .and_then(|x: &mut i32| {
53 *x += 10; // add 10
54 })
55 .and_then(|x: &mut i32| {
56 *x = *x * *x; // square
57 });
58
59 let mut value = 5;
60 println!("Initial value: {}", value);
61 chained.apply(&mut value);
62 println!("Result: {} (5 * 2 + 10 = 20, 20 * 20 = 400)\n", value);
63
64 // ========================================================================
65 // Example 3: Closure Extension Methods
66 // ========================================================================
67 println!("Example 3: Direct Use of Closure Extension Methods");
68 println!("{}", "-".repeat(50));
69
70 let closure_chain = (|x: &mut i32| *x *= 2).and_then(|x: &mut i32| *x += 10);
71
72 let mut value = 5;
73 println!("Initial value: {}", value);
74 closure_chain.apply(&mut value);
75 println!("Result: {} (5 * 2 + 10 = 20)\n", value);
76
77 // ========================================================================
78 // Example 4: BoxMutator Factory Methods
79 // ========================================================================
80 println!("Example 4: BoxMutator Factory Methods");
81 println!("{}", "-".repeat(50));
82
83 // noop
84 let noop = BoxMutator::<i32>::noop();
85 let mut value = 42;
86 println!("Before noop: {}", value);
87 noop.apply(&mut value);
88 println!("After noop: {} (unchanged)\n", value);
89
90 // ========================================================================
91 // Example 5: Conditional Mutator
92 // ========================================================================
93 println!("Example 5: Conditional Mutator");
94 println!("{}", "-".repeat(50));
95
96 // when (conditional execution)
97 let increment_if_positive = BoxMutator::new(|x: &mut i32| *x += 1).when(|x: &i32| *x > 0);
98
99 let mut positive = 5;
100 let mut negative = -5;
101 println!(
102 "Before when - positive: {}, negative: {}",
103 positive, negative
104 );
105 increment_if_positive.apply(&mut positive);
106 increment_if_positive.apply(&mut negative);
107 println!(
108 "After when - positive: {}, negative: {}\n",
109 positive, negative
110 );
111
112 // when().or_else() (conditional branching)
113 let adjust = BoxMutator::new(|x: &mut i32| *x *= 2)
114 .when(|x: &i32| *x > 0)
115 .or_else(|x: &mut i32| *x = -*x);
116
117 let mut positive = 10;
118 let mut negative = -10;
119 println!(
120 "Before when().or_else() - positive: {}, negative: {}",
121 positive, negative
122 );
123 adjust.apply(&mut positive);
124 adjust.apply(&mut negative);
125 println!(
126 "After when().or_else() - positive: {}, negative: {}\n",
127 positive, negative
128 );
129
130 // ========================================================================
131 // Example 6: ArcMutator - Multi-threaded Sharing
132 // ========================================================================
133 println!("Example 6: ArcMutator - Multi-threaded Sharing");
134 println!("{}", "-".repeat(50));
135
136 let shared = ArcMutator::new(|x: &mut i32| *x *= 2);
137
138 // Clone for another thread
139 let shared_clone = shared.clone();
140 let handle = thread::spawn(move || {
141 let mut value = 5;
142 let mutator = shared_clone;
143 mutator.apply(&mut value);
144 println!("In thread: 5 * 2 = {}", value);
145 value
146 });
147
148 // Use in main thread
149 let mut value = 3;
150 let mutator = shared;
151 mutator.apply(&mut value);
152 println!("Main thread: 3 * 2 = {}", value);
153
154 let thread_result = handle.join().unwrap();
155 println!("Thread result: {}\n", thread_result);
156
157 // ========================================================================
158 // Example 7: ArcMutator Composition (without consuming original mutator)
159 // ========================================================================
160 println!("Example 7: ArcMutator Composition (borrowing &self)");
161 println!("{}", "-".repeat(50));
162
163 let double = ArcMutator::new(|x: &mut i32| *x *= 2);
164 let add_ten = ArcMutator::new(|x: &mut i32| *x += 10);
165
166 // Composition doesn't consume the original mutator
167 let pipeline1 = double.and_then(add_ten.clone());
168 let pipeline2 = add_ten.and_then(double.clone());
169
170 let mut value1 = 5;
171 let p1 = pipeline1;
172 p1.apply(&mut value1);
173 println!("pipeline1 (double then add): 5 -> {}", value1);
174
175 let mut value2 = 5;
176 let p2 = pipeline2;
177 p2.apply(&mut value2);
178 println!("pipeline2 (add then double): 5 -> {}", value2);
179
180 // double and add_ten are still available
181 let mut value3 = 10;
182 let d = double;
183 d.apply(&mut value3);
184 println!("Original double still available: 10 -> {}\n", value3);
185
186 // ========================================================================
187 // Example 8: RcMutator - Single-threaded Sharing
188 // ========================================================================
189 println!("Example 8: RcMutator - Single-threaded Sharing");
190 println!("{}", "-".repeat(50));
191
192 let rc_mutator = RcMutator::new(|x: &mut i32| *x *= 2);
193
194 // Clone multiple copies
195 let clone1 = rc_mutator.clone();
196 let clone2 = rc_mutator.clone();
197
198 let mut value1 = 5;
199 let c1 = clone1;
200 c1.apply(&mut value1);
201 println!("clone1: 5 -> {}", value1);
202
203 let mut value2 = 3;
204 let c2 = clone2;
205 c2.apply(&mut value2);
206 println!("clone2: 3 -> {}", value2);
207
208 let mut value3 = 7;
209 let c3 = rc_mutator;
210 c3.apply(&mut value3);
211 println!("Original: 7 -> {}\n", value3);
212
213 // ========================================================================
214 // Example 9: RcMutator Composition (borrowing &self)
215 // ========================================================================
216 println!("Example 9: RcMutator Composition (borrowing &self)");
217 println!("{}", "-".repeat(50));
218
219 let double = RcMutator::new(|x: &mut i32| *x *= 2);
220 let add_ten = RcMutator::new(|x: &mut i32| *x += 10);
221
222 let pipeline1 = double.and_then(add_ten.clone());
223 let pipeline2 = add_ten.and_then(double.clone());
224
225 let mut value1 = 5;
226 let p1 = pipeline1;
227 p1.apply(&mut value1);
228 println!("pipeline1 (double then add): 5 -> {}", value1);
229
230 let mut value2 = 5;
231 let p2 = pipeline2;
232 p2.apply(&mut value2);
233 println!("pipeline2 (add then double): 5 -> {}\n", value2);
234
235 // ========================================================================
236 // Example 10: Unified Mutator trait
237 // ========================================================================
238 println!("Example 10: Unified Mutator trait");
239 println!("{}", "-".repeat(50));
240
241 fn apply_to_all<M: Mutator<i32>>(mutator: &mut M, values: &mut [i32]) {
242 for value in values.iter_mut() {
243 mutator.apply(value);
244 }
245 }
246
247 let mut values1 = vec![1, 2, 3, 4, 5];
248 let mut box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
249 println!("Using BoxMutator: {:?}", values1);
250 apply_to_all(&mut box_mut, &mut values1);
251 println!("Result: {:?}", values1);
252
253 let mut values2 = vec![1, 2, 3, 4, 5];
254 let mut arc_mut = ArcMutator::new(|x: &mut i32| *x *= 2);
255 println!("Using ArcMutator: {:?}", values2);
256 apply_to_all(&mut arc_mut, &mut values2);
257 println!("Result: {:?}", values2);
258
259 let mut values3 = vec![1, 2, 3, 4, 5];
260 let mut rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
261 println!("Using RcMutator: {:?}", values3);
262 apply_to_all(&mut rc_mut, &mut values3);
263 println!("Result: {:?}", values3);
264
265 let mut values4 = vec![1, 2, 3, 4, 5];
266 let mut closure = |x: &mut i32| *x *= 2;
267 println!("Using closure: {:?}", values4);
268 apply_to_all(&mut closure, &mut values4);
269 println!("Result: {:?}\n", values4);
270
271 // ========================================================================
272 // Example 11: Complex Data Processing Pipeline
273 // ========================================================================
274 println!("Example 11: Complex Data Processing Pipeline");
275 println!("{}", "-".repeat(50));
276
277 let pipeline = BoxMutator::new(|x: &mut i32| {
278 // Validation: clamp to 0-100
279 *x = (*x).clamp(0, 100);
280 })
281 .and_then(|x: &mut i32| {
282 // Normalization: scale to 0-10
283 *x /= 10;
284 })
285 .and_then(|x: &mut i32| {
286 // Transformation: square
287 *x = *x * *x;
288 });
289
290 let mut value1 = -50;
291 pipeline.apply(&mut value1);
292 println!("-50 -> {}", value1);
293
294 let mut value2 = 200;
295 pipeline.apply(&mut value2);
296 println!("200 -> {}", value2);
297
298 let mut value3 = 30;
299 pipeline.apply(&mut value3);
300 println!("30 -> {}\n", value3);
301
302 // ========================================================================
303 // Example 12: String Processing
304 // ========================================================================
305 println!("Example 12: String Processing");
306 println!("{}", "-".repeat(50));
307
308 let string_processor = BoxMutator::new(|s: &mut String| s.retain(|c| !c.is_whitespace()))
309 .and_then(|s: &mut String| *s = s.to_lowercase())
310 .and_then(|s: &mut String| s.push_str("!!!"));
311
312 let mut text = String::from("Hello World");
313 println!("Original: {}", text);
314 string_processor.apply(&mut text);
315 println!("After processing: {}\n", text);
316
317 // ========================================================================
318 // Example 13: Type Conversion
319 // ========================================================================
320 println!("Example 13: Type Conversion");
321 println!("{}", "-".repeat(50));
322
323 // Closure -> BoxMutator
324 let closure = |x: &mut i32| *x *= 2;
325 let box_mut = closure.into_box();
326 let mut value = 5;
327 box_mut.apply(&mut value);
328 println!("Closure -> BoxMutator: 5 -> {}", value);
329
330 // Closure -> RcMutator
331 let closure = |x: &mut i32| *x *= 2;
332 let rc_mut = closure.into_rc();
333 let mut value = 5;
334 rc_mut.apply(&mut value);
335 println!("Closure -> RcMutator: 5 -> {}", value);
336
337 // Closure -> ArcMutator
338 let closure = |x: &mut i32| *x *= 2;
339 let arc_mut = closure.into_arc();
340 let mut value = 5;
341 arc_mut.apply(&mut value);
342 println!("Closure -> ArcMutator: 5 -> {}", value);
343
344 // BoxMutator -> RcMutator
345 let box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
346 let rc_mut = box_mut.into_rc();
347 let mut value = 5;
348 rc_mut.apply(&mut value);
349 println!("BoxMutator -> RcMutator: 5 -> {}", value);
350
351 // RcMutator -> BoxMutator
352 let rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
353 let box_mut = rc_mut.into_box();
354 let mut value = 5;
355 box_mut.apply(&mut value);
356 println!("RcMutator -> BoxMutator: 5 -> {}\n", value);
357
358 // ========================================================================
359 // Example 14: Custom Types
360 // ========================================================================
361 println!("Example 14: Custom Types");
362 println!("{}", "-".repeat(50));
363
364 #[derive(Debug, Clone)]
365 struct Point {
366 x: i32,
367 y: i32,
368 }
369
370 let processor = BoxMutator::new(|p: &mut Point| p.x *= 2)
371 .and_then(|p: &mut Point| p.y *= 2)
372 .and_then(|p: &mut Point| p.x += p.y);
373
374 let mut point = Point { x: 3, y: 4 };
375 println!("Original point: {:?}", point);
376 processor.apply(&mut point);
377 println!("After processing: {:?}\n", point);
378
379 println!("=== All Examples Completed ===");
380}Sourcefn into_rc(self) -> RcMutator<T>where
Self: Sized + 'static,
fn into_rc(self) -> RcMutator<T>where
Self: Sized + '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 qubit_function::Mutator;
let closure = |x: &mut i32| *x *= 2;
let mut rc = closure.into_rc();
let mut value = 5;
rc.apply(&mut value);
assert_eq!(value, 10);Examples found in repository?
26fn main() {
27 println!("=== Mutator Demo ===\n");
28
29 // ========================================================================
30 // Example 1: BoxMutator Basic Usage
31 // ========================================================================
32 println!("Example 1: BoxMutator Basic Usage");
33 println!("{}", "-".repeat(50));
34
35 let mutator = BoxMutator::new(|x: &mut i32| {
36 *x *= 2;
37 });
38 let mut value = 5;
39 println!("Initial value: {}", value);
40 mutator.apply(&mut value);
41 println!("After BoxMutator execution: {}\n", value);
42
43 // ========================================================================
44 // Example 2: BoxMutator Method Chaining
45 // ========================================================================
46 println!("Example 2: BoxMutator Method Chaining");
47 println!("{}", "-".repeat(50));
48
49 let chained = BoxMutator::new(|x: &mut i32| {
50 *x *= 2; // multiply by 2
51 })
52 .and_then(|x: &mut i32| {
53 *x += 10; // add 10
54 })
55 .and_then(|x: &mut i32| {
56 *x = *x * *x; // square
57 });
58
59 let mut value = 5;
60 println!("Initial value: {}", value);
61 chained.apply(&mut value);
62 println!("Result: {} (5 * 2 + 10 = 20, 20 * 20 = 400)\n", value);
63
64 // ========================================================================
65 // Example 3: Closure Extension Methods
66 // ========================================================================
67 println!("Example 3: Direct Use of Closure Extension Methods");
68 println!("{}", "-".repeat(50));
69
70 let closure_chain = (|x: &mut i32| *x *= 2).and_then(|x: &mut i32| *x += 10);
71
72 let mut value = 5;
73 println!("Initial value: {}", value);
74 closure_chain.apply(&mut value);
75 println!("Result: {} (5 * 2 + 10 = 20)\n", value);
76
77 // ========================================================================
78 // Example 4: BoxMutator Factory Methods
79 // ========================================================================
80 println!("Example 4: BoxMutator Factory Methods");
81 println!("{}", "-".repeat(50));
82
83 // noop
84 let noop = BoxMutator::<i32>::noop();
85 let mut value = 42;
86 println!("Before noop: {}", value);
87 noop.apply(&mut value);
88 println!("After noop: {} (unchanged)\n", value);
89
90 // ========================================================================
91 // Example 5: Conditional Mutator
92 // ========================================================================
93 println!("Example 5: Conditional Mutator");
94 println!("{}", "-".repeat(50));
95
96 // when (conditional execution)
97 let increment_if_positive = BoxMutator::new(|x: &mut i32| *x += 1).when(|x: &i32| *x > 0);
98
99 let mut positive = 5;
100 let mut negative = -5;
101 println!(
102 "Before when - positive: {}, negative: {}",
103 positive, negative
104 );
105 increment_if_positive.apply(&mut positive);
106 increment_if_positive.apply(&mut negative);
107 println!(
108 "After when - positive: {}, negative: {}\n",
109 positive, negative
110 );
111
112 // when().or_else() (conditional branching)
113 let adjust = BoxMutator::new(|x: &mut i32| *x *= 2)
114 .when(|x: &i32| *x > 0)
115 .or_else(|x: &mut i32| *x = -*x);
116
117 let mut positive = 10;
118 let mut negative = -10;
119 println!(
120 "Before when().or_else() - positive: {}, negative: {}",
121 positive, negative
122 );
123 adjust.apply(&mut positive);
124 adjust.apply(&mut negative);
125 println!(
126 "After when().or_else() - positive: {}, negative: {}\n",
127 positive, negative
128 );
129
130 // ========================================================================
131 // Example 6: ArcMutator - Multi-threaded Sharing
132 // ========================================================================
133 println!("Example 6: ArcMutator - Multi-threaded Sharing");
134 println!("{}", "-".repeat(50));
135
136 let shared = ArcMutator::new(|x: &mut i32| *x *= 2);
137
138 // Clone for another thread
139 let shared_clone = shared.clone();
140 let handle = thread::spawn(move || {
141 let mut value = 5;
142 let mutator = shared_clone;
143 mutator.apply(&mut value);
144 println!("In thread: 5 * 2 = {}", value);
145 value
146 });
147
148 // Use in main thread
149 let mut value = 3;
150 let mutator = shared;
151 mutator.apply(&mut value);
152 println!("Main thread: 3 * 2 = {}", value);
153
154 let thread_result = handle.join().unwrap();
155 println!("Thread result: {}\n", thread_result);
156
157 // ========================================================================
158 // Example 7: ArcMutator Composition (without consuming original mutator)
159 // ========================================================================
160 println!("Example 7: ArcMutator Composition (borrowing &self)");
161 println!("{}", "-".repeat(50));
162
163 let double = ArcMutator::new(|x: &mut i32| *x *= 2);
164 let add_ten = ArcMutator::new(|x: &mut i32| *x += 10);
165
166 // Composition doesn't consume the original mutator
167 let pipeline1 = double.and_then(add_ten.clone());
168 let pipeline2 = add_ten.and_then(double.clone());
169
170 let mut value1 = 5;
171 let p1 = pipeline1;
172 p1.apply(&mut value1);
173 println!("pipeline1 (double then add): 5 -> {}", value1);
174
175 let mut value2 = 5;
176 let p2 = pipeline2;
177 p2.apply(&mut value2);
178 println!("pipeline2 (add then double): 5 -> {}", value2);
179
180 // double and add_ten are still available
181 let mut value3 = 10;
182 let d = double;
183 d.apply(&mut value3);
184 println!("Original double still available: 10 -> {}\n", value3);
185
186 // ========================================================================
187 // Example 8: RcMutator - Single-threaded Sharing
188 // ========================================================================
189 println!("Example 8: RcMutator - Single-threaded Sharing");
190 println!("{}", "-".repeat(50));
191
192 let rc_mutator = RcMutator::new(|x: &mut i32| *x *= 2);
193
194 // Clone multiple copies
195 let clone1 = rc_mutator.clone();
196 let clone2 = rc_mutator.clone();
197
198 let mut value1 = 5;
199 let c1 = clone1;
200 c1.apply(&mut value1);
201 println!("clone1: 5 -> {}", value1);
202
203 let mut value2 = 3;
204 let c2 = clone2;
205 c2.apply(&mut value2);
206 println!("clone2: 3 -> {}", value2);
207
208 let mut value3 = 7;
209 let c3 = rc_mutator;
210 c3.apply(&mut value3);
211 println!("Original: 7 -> {}\n", value3);
212
213 // ========================================================================
214 // Example 9: RcMutator Composition (borrowing &self)
215 // ========================================================================
216 println!("Example 9: RcMutator Composition (borrowing &self)");
217 println!("{}", "-".repeat(50));
218
219 let double = RcMutator::new(|x: &mut i32| *x *= 2);
220 let add_ten = RcMutator::new(|x: &mut i32| *x += 10);
221
222 let pipeline1 = double.and_then(add_ten.clone());
223 let pipeline2 = add_ten.and_then(double.clone());
224
225 let mut value1 = 5;
226 let p1 = pipeline1;
227 p1.apply(&mut value1);
228 println!("pipeline1 (double then add): 5 -> {}", value1);
229
230 let mut value2 = 5;
231 let p2 = pipeline2;
232 p2.apply(&mut value2);
233 println!("pipeline2 (add then double): 5 -> {}\n", value2);
234
235 // ========================================================================
236 // Example 10: Unified Mutator trait
237 // ========================================================================
238 println!("Example 10: Unified Mutator trait");
239 println!("{}", "-".repeat(50));
240
241 fn apply_to_all<M: Mutator<i32>>(mutator: &mut M, values: &mut [i32]) {
242 for value in values.iter_mut() {
243 mutator.apply(value);
244 }
245 }
246
247 let mut values1 = vec![1, 2, 3, 4, 5];
248 let mut box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
249 println!("Using BoxMutator: {:?}", values1);
250 apply_to_all(&mut box_mut, &mut values1);
251 println!("Result: {:?}", values1);
252
253 let mut values2 = vec![1, 2, 3, 4, 5];
254 let mut arc_mut = ArcMutator::new(|x: &mut i32| *x *= 2);
255 println!("Using ArcMutator: {:?}", values2);
256 apply_to_all(&mut arc_mut, &mut values2);
257 println!("Result: {:?}", values2);
258
259 let mut values3 = vec![1, 2, 3, 4, 5];
260 let mut rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
261 println!("Using RcMutator: {:?}", values3);
262 apply_to_all(&mut rc_mut, &mut values3);
263 println!("Result: {:?}", values3);
264
265 let mut values4 = vec![1, 2, 3, 4, 5];
266 let mut closure = |x: &mut i32| *x *= 2;
267 println!("Using closure: {:?}", values4);
268 apply_to_all(&mut closure, &mut values4);
269 println!("Result: {:?}\n", values4);
270
271 // ========================================================================
272 // Example 11: Complex Data Processing Pipeline
273 // ========================================================================
274 println!("Example 11: Complex Data Processing Pipeline");
275 println!("{}", "-".repeat(50));
276
277 let pipeline = BoxMutator::new(|x: &mut i32| {
278 // Validation: clamp to 0-100
279 *x = (*x).clamp(0, 100);
280 })
281 .and_then(|x: &mut i32| {
282 // Normalization: scale to 0-10
283 *x /= 10;
284 })
285 .and_then(|x: &mut i32| {
286 // Transformation: square
287 *x = *x * *x;
288 });
289
290 let mut value1 = -50;
291 pipeline.apply(&mut value1);
292 println!("-50 -> {}", value1);
293
294 let mut value2 = 200;
295 pipeline.apply(&mut value2);
296 println!("200 -> {}", value2);
297
298 let mut value3 = 30;
299 pipeline.apply(&mut value3);
300 println!("30 -> {}\n", value3);
301
302 // ========================================================================
303 // Example 12: String Processing
304 // ========================================================================
305 println!("Example 12: String Processing");
306 println!("{}", "-".repeat(50));
307
308 let string_processor = BoxMutator::new(|s: &mut String| s.retain(|c| !c.is_whitespace()))
309 .and_then(|s: &mut String| *s = s.to_lowercase())
310 .and_then(|s: &mut String| s.push_str("!!!"));
311
312 let mut text = String::from("Hello World");
313 println!("Original: {}", text);
314 string_processor.apply(&mut text);
315 println!("After processing: {}\n", text);
316
317 // ========================================================================
318 // Example 13: Type Conversion
319 // ========================================================================
320 println!("Example 13: Type Conversion");
321 println!("{}", "-".repeat(50));
322
323 // Closure -> BoxMutator
324 let closure = |x: &mut i32| *x *= 2;
325 let box_mut = closure.into_box();
326 let mut value = 5;
327 box_mut.apply(&mut value);
328 println!("Closure -> BoxMutator: 5 -> {}", value);
329
330 // Closure -> RcMutator
331 let closure = |x: &mut i32| *x *= 2;
332 let rc_mut = closure.into_rc();
333 let mut value = 5;
334 rc_mut.apply(&mut value);
335 println!("Closure -> RcMutator: 5 -> {}", value);
336
337 // Closure -> ArcMutator
338 let closure = |x: &mut i32| *x *= 2;
339 let arc_mut = closure.into_arc();
340 let mut value = 5;
341 arc_mut.apply(&mut value);
342 println!("Closure -> ArcMutator: 5 -> {}", value);
343
344 // BoxMutator -> RcMutator
345 let box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
346 let rc_mut = box_mut.into_rc();
347 let mut value = 5;
348 rc_mut.apply(&mut value);
349 println!("BoxMutator -> RcMutator: 5 -> {}", value);
350
351 // RcMutator -> BoxMutator
352 let rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
353 let box_mut = rc_mut.into_box();
354 let mut value = 5;
355 box_mut.apply(&mut value);
356 println!("RcMutator -> BoxMutator: 5 -> {}\n", value);
357
358 // ========================================================================
359 // Example 14: Custom Types
360 // ========================================================================
361 println!("Example 14: Custom Types");
362 println!("{}", "-".repeat(50));
363
364 #[derive(Debug, Clone)]
365 struct Point {
366 x: i32,
367 y: i32,
368 }
369
370 let processor = BoxMutator::new(|p: &mut Point| p.x *= 2)
371 .and_then(|p: &mut Point| p.y *= 2)
372 .and_then(|p: &mut Point| p.x += p.y);
373
374 let mut point = Point { x: 3, y: 4 };
375 println!("Original point: {:?}", point);
376 processor.apply(&mut point);
377 println!("After processing: {:?}\n", point);
378
379 println!("=== All Examples Completed ===");
380}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 qubit_function::Mutator;
let closure = |x: &mut i32| *x *= 2;
let mut arc = closure.into_arc();
let mut value = 5;
arc.apply(&mut value);
assert_eq!(value, 10);Examples found in repository?
26fn main() {
27 println!("=== Mutator Demo ===\n");
28
29 // ========================================================================
30 // Example 1: BoxMutator Basic Usage
31 // ========================================================================
32 println!("Example 1: BoxMutator Basic Usage");
33 println!("{}", "-".repeat(50));
34
35 let mutator = BoxMutator::new(|x: &mut i32| {
36 *x *= 2;
37 });
38 let mut value = 5;
39 println!("Initial value: {}", value);
40 mutator.apply(&mut value);
41 println!("After BoxMutator execution: {}\n", value);
42
43 // ========================================================================
44 // Example 2: BoxMutator Method Chaining
45 // ========================================================================
46 println!("Example 2: BoxMutator Method Chaining");
47 println!("{}", "-".repeat(50));
48
49 let chained = BoxMutator::new(|x: &mut i32| {
50 *x *= 2; // multiply by 2
51 })
52 .and_then(|x: &mut i32| {
53 *x += 10; // add 10
54 })
55 .and_then(|x: &mut i32| {
56 *x = *x * *x; // square
57 });
58
59 let mut value = 5;
60 println!("Initial value: {}", value);
61 chained.apply(&mut value);
62 println!("Result: {} (5 * 2 + 10 = 20, 20 * 20 = 400)\n", value);
63
64 // ========================================================================
65 // Example 3: Closure Extension Methods
66 // ========================================================================
67 println!("Example 3: Direct Use of Closure Extension Methods");
68 println!("{}", "-".repeat(50));
69
70 let closure_chain = (|x: &mut i32| *x *= 2).and_then(|x: &mut i32| *x += 10);
71
72 let mut value = 5;
73 println!("Initial value: {}", value);
74 closure_chain.apply(&mut value);
75 println!("Result: {} (5 * 2 + 10 = 20)\n", value);
76
77 // ========================================================================
78 // Example 4: BoxMutator Factory Methods
79 // ========================================================================
80 println!("Example 4: BoxMutator Factory Methods");
81 println!("{}", "-".repeat(50));
82
83 // noop
84 let noop = BoxMutator::<i32>::noop();
85 let mut value = 42;
86 println!("Before noop: {}", value);
87 noop.apply(&mut value);
88 println!("After noop: {} (unchanged)\n", value);
89
90 // ========================================================================
91 // Example 5: Conditional Mutator
92 // ========================================================================
93 println!("Example 5: Conditional Mutator");
94 println!("{}", "-".repeat(50));
95
96 // when (conditional execution)
97 let increment_if_positive = BoxMutator::new(|x: &mut i32| *x += 1).when(|x: &i32| *x > 0);
98
99 let mut positive = 5;
100 let mut negative = -5;
101 println!(
102 "Before when - positive: {}, negative: {}",
103 positive, negative
104 );
105 increment_if_positive.apply(&mut positive);
106 increment_if_positive.apply(&mut negative);
107 println!(
108 "After when - positive: {}, negative: {}\n",
109 positive, negative
110 );
111
112 // when().or_else() (conditional branching)
113 let adjust = BoxMutator::new(|x: &mut i32| *x *= 2)
114 .when(|x: &i32| *x > 0)
115 .or_else(|x: &mut i32| *x = -*x);
116
117 let mut positive = 10;
118 let mut negative = -10;
119 println!(
120 "Before when().or_else() - positive: {}, negative: {}",
121 positive, negative
122 );
123 adjust.apply(&mut positive);
124 adjust.apply(&mut negative);
125 println!(
126 "After when().or_else() - positive: {}, negative: {}\n",
127 positive, negative
128 );
129
130 // ========================================================================
131 // Example 6: ArcMutator - Multi-threaded Sharing
132 // ========================================================================
133 println!("Example 6: ArcMutator - Multi-threaded Sharing");
134 println!("{}", "-".repeat(50));
135
136 let shared = ArcMutator::new(|x: &mut i32| *x *= 2);
137
138 // Clone for another thread
139 let shared_clone = shared.clone();
140 let handle = thread::spawn(move || {
141 let mut value = 5;
142 let mutator = shared_clone;
143 mutator.apply(&mut value);
144 println!("In thread: 5 * 2 = {}", value);
145 value
146 });
147
148 // Use in main thread
149 let mut value = 3;
150 let mutator = shared;
151 mutator.apply(&mut value);
152 println!("Main thread: 3 * 2 = {}", value);
153
154 let thread_result = handle.join().unwrap();
155 println!("Thread result: {}\n", thread_result);
156
157 // ========================================================================
158 // Example 7: ArcMutator Composition (without consuming original mutator)
159 // ========================================================================
160 println!("Example 7: ArcMutator Composition (borrowing &self)");
161 println!("{}", "-".repeat(50));
162
163 let double = ArcMutator::new(|x: &mut i32| *x *= 2);
164 let add_ten = ArcMutator::new(|x: &mut i32| *x += 10);
165
166 // Composition doesn't consume the original mutator
167 let pipeline1 = double.and_then(add_ten.clone());
168 let pipeline2 = add_ten.and_then(double.clone());
169
170 let mut value1 = 5;
171 let p1 = pipeline1;
172 p1.apply(&mut value1);
173 println!("pipeline1 (double then add): 5 -> {}", value1);
174
175 let mut value2 = 5;
176 let p2 = pipeline2;
177 p2.apply(&mut value2);
178 println!("pipeline2 (add then double): 5 -> {}", value2);
179
180 // double and add_ten are still available
181 let mut value3 = 10;
182 let d = double;
183 d.apply(&mut value3);
184 println!("Original double still available: 10 -> {}\n", value3);
185
186 // ========================================================================
187 // Example 8: RcMutator - Single-threaded Sharing
188 // ========================================================================
189 println!("Example 8: RcMutator - Single-threaded Sharing");
190 println!("{}", "-".repeat(50));
191
192 let rc_mutator = RcMutator::new(|x: &mut i32| *x *= 2);
193
194 // Clone multiple copies
195 let clone1 = rc_mutator.clone();
196 let clone2 = rc_mutator.clone();
197
198 let mut value1 = 5;
199 let c1 = clone1;
200 c1.apply(&mut value1);
201 println!("clone1: 5 -> {}", value1);
202
203 let mut value2 = 3;
204 let c2 = clone2;
205 c2.apply(&mut value2);
206 println!("clone2: 3 -> {}", value2);
207
208 let mut value3 = 7;
209 let c3 = rc_mutator;
210 c3.apply(&mut value3);
211 println!("Original: 7 -> {}\n", value3);
212
213 // ========================================================================
214 // Example 9: RcMutator Composition (borrowing &self)
215 // ========================================================================
216 println!("Example 9: RcMutator Composition (borrowing &self)");
217 println!("{}", "-".repeat(50));
218
219 let double = RcMutator::new(|x: &mut i32| *x *= 2);
220 let add_ten = RcMutator::new(|x: &mut i32| *x += 10);
221
222 let pipeline1 = double.and_then(add_ten.clone());
223 let pipeline2 = add_ten.and_then(double.clone());
224
225 let mut value1 = 5;
226 let p1 = pipeline1;
227 p1.apply(&mut value1);
228 println!("pipeline1 (double then add): 5 -> {}", value1);
229
230 let mut value2 = 5;
231 let p2 = pipeline2;
232 p2.apply(&mut value2);
233 println!("pipeline2 (add then double): 5 -> {}\n", value2);
234
235 // ========================================================================
236 // Example 10: Unified Mutator trait
237 // ========================================================================
238 println!("Example 10: Unified Mutator trait");
239 println!("{}", "-".repeat(50));
240
241 fn apply_to_all<M: Mutator<i32>>(mutator: &mut M, values: &mut [i32]) {
242 for value in values.iter_mut() {
243 mutator.apply(value);
244 }
245 }
246
247 let mut values1 = vec![1, 2, 3, 4, 5];
248 let mut box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
249 println!("Using BoxMutator: {:?}", values1);
250 apply_to_all(&mut box_mut, &mut values1);
251 println!("Result: {:?}", values1);
252
253 let mut values2 = vec![1, 2, 3, 4, 5];
254 let mut arc_mut = ArcMutator::new(|x: &mut i32| *x *= 2);
255 println!("Using ArcMutator: {:?}", values2);
256 apply_to_all(&mut arc_mut, &mut values2);
257 println!("Result: {:?}", values2);
258
259 let mut values3 = vec![1, 2, 3, 4, 5];
260 let mut rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
261 println!("Using RcMutator: {:?}", values3);
262 apply_to_all(&mut rc_mut, &mut values3);
263 println!("Result: {:?}", values3);
264
265 let mut values4 = vec![1, 2, 3, 4, 5];
266 let mut closure = |x: &mut i32| *x *= 2;
267 println!("Using closure: {:?}", values4);
268 apply_to_all(&mut closure, &mut values4);
269 println!("Result: {:?}\n", values4);
270
271 // ========================================================================
272 // Example 11: Complex Data Processing Pipeline
273 // ========================================================================
274 println!("Example 11: Complex Data Processing Pipeline");
275 println!("{}", "-".repeat(50));
276
277 let pipeline = BoxMutator::new(|x: &mut i32| {
278 // Validation: clamp to 0-100
279 *x = (*x).clamp(0, 100);
280 })
281 .and_then(|x: &mut i32| {
282 // Normalization: scale to 0-10
283 *x /= 10;
284 })
285 .and_then(|x: &mut i32| {
286 // Transformation: square
287 *x = *x * *x;
288 });
289
290 let mut value1 = -50;
291 pipeline.apply(&mut value1);
292 println!("-50 -> {}", value1);
293
294 let mut value2 = 200;
295 pipeline.apply(&mut value2);
296 println!("200 -> {}", value2);
297
298 let mut value3 = 30;
299 pipeline.apply(&mut value3);
300 println!("30 -> {}\n", value3);
301
302 // ========================================================================
303 // Example 12: String Processing
304 // ========================================================================
305 println!("Example 12: String Processing");
306 println!("{}", "-".repeat(50));
307
308 let string_processor = BoxMutator::new(|s: &mut String| s.retain(|c| !c.is_whitespace()))
309 .and_then(|s: &mut String| *s = s.to_lowercase())
310 .and_then(|s: &mut String| s.push_str("!!!"));
311
312 let mut text = String::from("Hello World");
313 println!("Original: {}", text);
314 string_processor.apply(&mut text);
315 println!("After processing: {}\n", text);
316
317 // ========================================================================
318 // Example 13: Type Conversion
319 // ========================================================================
320 println!("Example 13: Type Conversion");
321 println!("{}", "-".repeat(50));
322
323 // Closure -> BoxMutator
324 let closure = |x: &mut i32| *x *= 2;
325 let box_mut = closure.into_box();
326 let mut value = 5;
327 box_mut.apply(&mut value);
328 println!("Closure -> BoxMutator: 5 -> {}", value);
329
330 // Closure -> RcMutator
331 let closure = |x: &mut i32| *x *= 2;
332 let rc_mut = closure.into_rc();
333 let mut value = 5;
334 rc_mut.apply(&mut value);
335 println!("Closure -> RcMutator: 5 -> {}", value);
336
337 // Closure -> ArcMutator
338 let closure = |x: &mut i32| *x *= 2;
339 let arc_mut = closure.into_arc();
340 let mut value = 5;
341 arc_mut.apply(&mut value);
342 println!("Closure -> ArcMutator: 5 -> {}", value);
343
344 // BoxMutator -> RcMutator
345 let box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
346 let rc_mut = box_mut.into_rc();
347 let mut value = 5;
348 rc_mut.apply(&mut value);
349 println!("BoxMutator -> RcMutator: 5 -> {}", value);
350
351 // RcMutator -> BoxMutator
352 let rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
353 let box_mut = rc_mut.into_box();
354 let mut value = 5;
355 box_mut.apply(&mut value);
356 println!("RcMutator -> BoxMutator: 5 -> {}\n", value);
357
358 // ========================================================================
359 // Example 14: Custom Types
360 // ========================================================================
361 println!("Example 14: Custom Types");
362 println!("{}", "-".repeat(50));
363
364 #[derive(Debug, Clone)]
365 struct Point {
366 x: i32,
367 y: i32,
368 }
369
370 let processor = BoxMutator::new(|p: &mut Point| p.x *= 2)
371 .and_then(|p: &mut Point| p.y *= 2)
372 .and_then(|p: &mut Point| p.x += p.y);
373
374 let mut point = Point { x: 3, y: 4 };
375 println!("Original point: {:?}", point);
376 processor.apply(&mut point);
377 println!("After processing: {:?}\n", point);
378
379 println!("=== All Examples Completed ===");
380}Sourcefn into_fn(self) -> impl Fn(&mut T)where
Self: Sized + 'static,
fn into_fn(self) -> impl Fn(&mut T)where
Self: Sized + 'static,
Consume the mutator and return an Fn(&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 Fn(&mut T) which forwards to the
original mutator.
§Examples
use qubit_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 into_once(self) -> BoxMutatorOnce<T>where
Self: Sized + 'static,
fn into_once(self) -> BoxMutatorOnce<T>where
Self: Sized + 'static,
Convert this mutator into a BoxMutatorOnce<T> (consuming).
This consuming conversion takes ownership of self and returns a
boxed one-time mutator that forwards calls to the original mutator.
The returned mutator can only be used once.
§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 BoxMutatorOnce<T> that forwards to the original mutator.
§Examples
use qubit_function::{Mutator, MutatorOnce, BoxMutator, BoxMutatorOnce};
let mutator = BoxMutator::new(|x: &mut i32| *x *= 2);
let once_mutator = mutator.into_once();
let mut value = 5;
once_mutator.apply(&mut value);
assert_eq!(value, 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 + Sync) 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 Fn(&mut T)
fn to_fn(&self) -> impl Fn(&mut T)
Create a boxed Fn(&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 Fn(&mut T) which forwards to the
original mutator.
Sourcefn to_once(&self) -> BoxMutatorOnce<T>
fn to_once(&self) -> BoxMutatorOnce<T>
Create a non-consuming BoxMutatorOnce<T> that forwards to self.
The default implementation clones self (requires Clone) and
returns a boxed one-time mutator that calls the cloned instance.
Override this method if a more efficient conversion exists.
§Returns
A BoxMutatorOnce<T> that forwards to a clone of self.