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 movedRequired 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?
27fn main() {
28 println!("=== Mutator Demo ===\n");
29
30 // ========================================================================
31 // Example 1: BoxMutator Basic Usage
32 // ========================================================================
33 println!("Example 1: BoxMutator Basic Usage");
34 println!("{}", "-".repeat(50));
35
36 let mutator = BoxMutator::new(|x: &mut i32| {
37 *x *= 2;
38 });
39 let mut value = 5;
40 println!("Initial value: {}", value);
41 mutator.apply(&mut value);
42 println!("After BoxMutator execution: {}\n", value);
43
44 // ========================================================================
45 // Example 2: BoxMutator Method Chaining
46 // ========================================================================
47 println!("Example 2: BoxMutator Method Chaining");
48 println!("{}", "-".repeat(50));
49
50 let chained = BoxMutator::new(|x: &mut i32| {
51 *x *= 2; // multiply by 2
52 })
53 .and_then(|x: &mut i32| {
54 *x += 10; // add 10
55 })
56 .and_then(|x: &mut i32| {
57 *x = *x * *x; // square
58 });
59
60 let mut value = 5;
61 println!("Initial value: {}", value);
62 chained.apply(&mut value);
63 println!("Result: {} (5 * 2 + 10 = 20, 20 * 20 = 400)\n", value);
64
65 // ========================================================================
66 // Example 3: Closure Extension Methods
67 // ========================================================================
68 println!("Example 3: Direct Use of Closure Extension Methods");
69 println!("{}", "-".repeat(50));
70
71 let closure_chain = (|x: &mut i32| *x *= 2).and_then(|x: &mut i32| *x += 10);
72
73 let mut value = 5;
74 println!("Initial value: {}", value);
75 closure_chain.apply(&mut value);
76 println!("Result: {} (5 * 2 + 10 = 20)\n", value);
77
78 // ========================================================================
79 // Example 4: BoxMutator Factory Methods
80 // ========================================================================
81 println!("Example 4: BoxMutator Factory Methods");
82 println!("{}", "-".repeat(50));
83
84 // noop
85 let noop = BoxMutator::<i32>::noop();
86 let mut value = 42;
87 println!("Before noop: {}", value);
88 noop.apply(&mut value);
89 println!("After noop: {} (unchanged)\n", value);
90
91 // ========================================================================
92 // Example 5: Conditional Mutator
93 // ========================================================================
94 println!("Example 5: Conditional Mutator");
95 println!("{}", "-".repeat(50));
96
97 // when (conditional execution)
98 let increment_if_positive = BoxMutator::new(|x: &mut i32| *x += 1).when(|x: &i32| *x > 0);
99
100 let mut positive = 5;
101 let mut negative = -5;
102 println!(
103 "Before when - positive: {}, negative: {}",
104 positive, negative
105 );
106 increment_if_positive.apply(&mut positive);
107 increment_if_positive.apply(&mut negative);
108 println!(
109 "After when - positive: {}, negative: {}\n",
110 positive, negative
111 );
112
113 // when().or_else() (conditional branching)
114 let adjust = BoxMutator::new(|x: &mut i32| *x *= 2)
115 .when(|x: &i32| *x > 0)
116 .or_else(|x: &mut i32| *x = -*x);
117
118 let mut positive = 10;
119 let mut negative = -10;
120 println!(
121 "Before when().or_else() - positive: {}, negative: {}",
122 positive, negative
123 );
124 adjust.apply(&mut positive);
125 adjust.apply(&mut negative);
126 println!(
127 "After when().or_else() - positive: {}, negative: {}\n",
128 positive, negative
129 );
130
131 // ========================================================================
132 // Example 6: ArcMutator - Multi-threaded Sharing
133 // ========================================================================
134 println!("Example 6: ArcMutator - Multi-threaded Sharing");
135 println!("{}", "-".repeat(50));
136
137 let shared = ArcMutator::new(|x: &mut i32| *x *= 2);
138
139 // Clone for another thread
140 let shared_clone = shared.clone();
141 let handle = thread::spawn(move || {
142 let mut value = 5;
143 let mutator = shared_clone;
144 mutator.apply(&mut value);
145 println!("In thread: 5 * 2 = {}", value);
146 value
147 });
148
149 // Use in main thread
150 let mut value = 3;
151 let mutator = shared;
152 mutator.apply(&mut value);
153 println!("Main thread: 3 * 2 = {}", value);
154
155 let thread_result = handle.join().unwrap();
156 println!("Thread result: {}\n", thread_result);
157
158 // ========================================================================
159 // Example 7: ArcMutator Composition (without consuming original mutator)
160 // ========================================================================
161 println!("Example 7: ArcMutator Composition (borrowing &self)");
162 println!("{}", "-".repeat(50));
163
164 let double = ArcMutator::new(|x: &mut i32| *x *= 2);
165 let add_ten = ArcMutator::new(|x: &mut i32| *x += 10);
166
167 // Composition doesn't consume the original mutator
168 let pipeline1 = double.and_then(add_ten.clone());
169 let pipeline2 = add_ten.and_then(double.clone());
170
171 let mut value1 = 5;
172 let p1 = pipeline1;
173 p1.apply(&mut value1);
174 println!("pipeline1 (double then add): 5 -> {}", value1);
175
176 let mut value2 = 5;
177 let p2 = pipeline2;
178 p2.apply(&mut value2);
179 println!("pipeline2 (add then double): 5 -> {}", value2);
180
181 // double and add_ten are still available
182 let mut value3 = 10;
183 let d = double;
184 d.apply(&mut value3);
185 println!("Original double still available: 10 -> {}\n", value3);
186
187 // ========================================================================
188 // Example 8: RcMutator - Single-threaded Sharing
189 // ========================================================================
190 println!("Example 8: RcMutator - Single-threaded Sharing");
191 println!("{}", "-".repeat(50));
192
193 let rc_mutator = RcMutator::new(|x: &mut i32| *x *= 2);
194
195 // Clone multiple copies
196 let clone1 = rc_mutator.clone();
197 let clone2 = rc_mutator.clone();
198
199 let mut value1 = 5;
200 let c1 = clone1;
201 c1.apply(&mut value1);
202 println!("clone1: 5 -> {}", value1);
203
204 let mut value2 = 3;
205 let c2 = clone2;
206 c2.apply(&mut value2);
207 println!("clone2: 3 -> {}", value2);
208
209 let mut value3 = 7;
210 let c3 = rc_mutator;
211 c3.apply(&mut value3);
212 println!("Original: 7 -> {}\n", value3);
213
214 // ========================================================================
215 // Example 9: RcMutator Composition (borrowing &self)
216 // ========================================================================
217 println!("Example 9: RcMutator Composition (borrowing &self)");
218 println!("{}", "-".repeat(50));
219
220 let double = RcMutator::new(|x: &mut i32| *x *= 2);
221 let add_ten = RcMutator::new(|x: &mut i32| *x += 10);
222
223 let pipeline1 = double.and_then(add_ten.clone());
224 let pipeline2 = add_ten.and_then(double.clone());
225
226 let mut value1 = 5;
227 let p1 = pipeline1;
228 p1.apply(&mut value1);
229 println!("pipeline1 (double then add): 5 -> {}", value1);
230
231 let mut value2 = 5;
232 let p2 = pipeline2;
233 p2.apply(&mut value2);
234 println!("pipeline2 (add then double): 5 -> {}\n", value2);
235
236 // ========================================================================
237 // Example 10: Unified Mutator trait
238 // ========================================================================
239 println!("Example 10: Unified Mutator trait");
240 println!("{}", "-".repeat(50));
241
242 fn apply_to_all<M: Mutator<i32>>(mutator: &mut M, values: &mut [i32]) {
243 for value in values.iter_mut() {
244 mutator.apply(value);
245 }
246 }
247
248 let mut values1 = vec![1, 2, 3, 4, 5];
249 let mut box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
250 println!("Using BoxMutator: {:?}", values1);
251 apply_to_all(&mut box_mut, &mut values1);
252 println!("Result: {:?}", values1);
253
254 let mut values2 = vec![1, 2, 3, 4, 5];
255 let mut arc_mut = ArcMutator::new(|x: &mut i32| *x *= 2);
256 println!("Using ArcMutator: {:?}", values2);
257 apply_to_all(&mut arc_mut, &mut values2);
258 println!("Result: {:?}", values2);
259
260 let mut values3 = vec![1, 2, 3, 4, 5];
261 let mut rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
262 println!("Using RcMutator: {:?}", values3);
263 apply_to_all(&mut rc_mut, &mut values3);
264 println!("Result: {:?}", values3);
265
266 let mut values4 = vec![1, 2, 3, 4, 5];
267 let mut closure = |x: &mut i32| *x *= 2;
268 println!("Using closure: {:?}", values4);
269 apply_to_all(&mut closure, &mut values4);
270 println!("Result: {:?}\n", values4);
271
272 // ========================================================================
273 // Example 11: Complex Data Processing Pipeline
274 // ========================================================================
275 println!("Example 11: Complex Data Processing Pipeline");
276 println!("{}", "-".repeat(50));
277
278 let pipeline = BoxMutator::new(|x: &mut i32| {
279 // Validation: clamp to 0-100
280 *x = (*x).clamp(0, 100);
281 })
282 .and_then(|x: &mut i32| {
283 // Normalization: scale to 0-10
284 *x /= 10;
285 })
286 .and_then(|x: &mut i32| {
287 // Transformation: square
288 *x = *x * *x;
289 });
290
291 let mut value1 = -50;
292 pipeline.apply(&mut value1);
293 println!("-50 -> {}", value1);
294
295 let mut value2 = 200;
296 pipeline.apply(&mut value2);
297 println!("200 -> {}", value2);
298
299 let mut value3 = 30;
300 pipeline.apply(&mut value3);
301 println!("30 -> {}\n", value3);
302
303 // ========================================================================
304 // Example 12: String Processing
305 // ========================================================================
306 println!("Example 12: String Processing");
307 println!("{}", "-".repeat(50));
308
309 let string_processor = BoxMutator::new(|s: &mut String| s.retain(|c| !c.is_whitespace()))
310 .and_then(|s: &mut String| *s = s.to_lowercase())
311 .and_then(|s: &mut String| s.push_str("!!!"));
312
313 let mut text = String::from("Hello World");
314 println!("Original: {}", text);
315 string_processor.apply(&mut text);
316 println!("After processing: {}\n", text);
317
318 // ========================================================================
319 // Example 13: Type Conversion
320 // ========================================================================
321 println!("Example 13: Type Conversion");
322 println!("{}", "-".repeat(50));
323
324 // Closure -> BoxMutator
325 let closure = |x: &mut i32| *x *= 2;
326 let box_mut = closure.into_box();
327 let mut value = 5;
328 box_mut.apply(&mut value);
329 println!("Closure -> BoxMutator: 5 -> {}", value);
330
331 // Closure -> RcMutator
332 let closure = |x: &mut i32| *x *= 2;
333 let rc_mut = closure.into_rc();
334 let mut value = 5;
335 rc_mut.apply(&mut value);
336 println!("Closure -> RcMutator: 5 -> {}", value);
337
338 // Closure -> ArcMutator
339 let closure = |x: &mut i32| *x *= 2;
340 let arc_mut = closure.into_arc();
341 let mut value = 5;
342 arc_mut.apply(&mut value);
343 println!("Closure -> ArcMutator: 5 -> {}", value);
344
345 // BoxMutator -> RcMutator
346 let box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
347 let rc_mut = box_mut.into_rc();
348 let mut value = 5;
349 rc_mut.apply(&mut value);
350 println!("BoxMutator -> RcMutator: 5 -> {}", value);
351
352 // RcMutator -> BoxMutator
353 let rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
354 let box_mut = rc_mut.into_box();
355 let mut value = 5;
356 box_mut.apply(&mut value);
357 println!("RcMutator -> BoxMutator: 5 -> {}\n", value);
358
359 // ========================================================================
360 // Example 14: Custom Types
361 // ========================================================================
362 println!("Example 14: Custom Types");
363 println!("{}", "-".repeat(50));
364
365 #[derive(Debug, Clone)]
366 struct Point {
367 x: i32,
368 y: i32,
369 }
370
371 let processor = BoxMutator::new(|p: &mut Point| p.x *= 2)
372 .and_then(|p: &mut Point| p.y *= 2)
373 .and_then(|p: &mut Point| p.x += p.y);
374
375 let mut point = Point { x: 3, y: 4 };
376 println!("Original point: {:?}", point);
377 processor.apply(&mut point);
378 println!("After processing: {:?}\n", point);
379
380 println!("=== All Examples Completed ===");
381}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?
27fn main() {
28 println!("=== Mutator Demo ===\n");
29
30 // ========================================================================
31 // Example 1: BoxMutator Basic Usage
32 // ========================================================================
33 println!("Example 1: BoxMutator Basic Usage");
34 println!("{}", "-".repeat(50));
35
36 let mutator = BoxMutator::new(|x: &mut i32| {
37 *x *= 2;
38 });
39 let mut value = 5;
40 println!("Initial value: {}", value);
41 mutator.apply(&mut value);
42 println!("After BoxMutator execution: {}\n", value);
43
44 // ========================================================================
45 // Example 2: BoxMutator Method Chaining
46 // ========================================================================
47 println!("Example 2: BoxMutator Method Chaining");
48 println!("{}", "-".repeat(50));
49
50 let chained = BoxMutator::new(|x: &mut i32| {
51 *x *= 2; // multiply by 2
52 })
53 .and_then(|x: &mut i32| {
54 *x += 10; // add 10
55 })
56 .and_then(|x: &mut i32| {
57 *x = *x * *x; // square
58 });
59
60 let mut value = 5;
61 println!("Initial value: {}", value);
62 chained.apply(&mut value);
63 println!("Result: {} (5 * 2 + 10 = 20, 20 * 20 = 400)\n", value);
64
65 // ========================================================================
66 // Example 3: Closure Extension Methods
67 // ========================================================================
68 println!("Example 3: Direct Use of Closure Extension Methods");
69 println!("{}", "-".repeat(50));
70
71 let closure_chain = (|x: &mut i32| *x *= 2).and_then(|x: &mut i32| *x += 10);
72
73 let mut value = 5;
74 println!("Initial value: {}", value);
75 closure_chain.apply(&mut value);
76 println!("Result: {} (5 * 2 + 10 = 20)\n", value);
77
78 // ========================================================================
79 // Example 4: BoxMutator Factory Methods
80 // ========================================================================
81 println!("Example 4: BoxMutator Factory Methods");
82 println!("{}", "-".repeat(50));
83
84 // noop
85 let noop = BoxMutator::<i32>::noop();
86 let mut value = 42;
87 println!("Before noop: {}", value);
88 noop.apply(&mut value);
89 println!("After noop: {} (unchanged)\n", value);
90
91 // ========================================================================
92 // Example 5: Conditional Mutator
93 // ========================================================================
94 println!("Example 5: Conditional Mutator");
95 println!("{}", "-".repeat(50));
96
97 // when (conditional execution)
98 let increment_if_positive = BoxMutator::new(|x: &mut i32| *x += 1).when(|x: &i32| *x > 0);
99
100 let mut positive = 5;
101 let mut negative = -5;
102 println!(
103 "Before when - positive: {}, negative: {}",
104 positive, negative
105 );
106 increment_if_positive.apply(&mut positive);
107 increment_if_positive.apply(&mut negative);
108 println!(
109 "After when - positive: {}, negative: {}\n",
110 positive, negative
111 );
112
113 // when().or_else() (conditional branching)
114 let adjust = BoxMutator::new(|x: &mut i32| *x *= 2)
115 .when(|x: &i32| *x > 0)
116 .or_else(|x: &mut i32| *x = -*x);
117
118 let mut positive = 10;
119 let mut negative = -10;
120 println!(
121 "Before when().or_else() - positive: {}, negative: {}",
122 positive, negative
123 );
124 adjust.apply(&mut positive);
125 adjust.apply(&mut negative);
126 println!(
127 "After when().or_else() - positive: {}, negative: {}\n",
128 positive, negative
129 );
130
131 // ========================================================================
132 // Example 6: ArcMutator - Multi-threaded Sharing
133 // ========================================================================
134 println!("Example 6: ArcMutator - Multi-threaded Sharing");
135 println!("{}", "-".repeat(50));
136
137 let shared = ArcMutator::new(|x: &mut i32| *x *= 2);
138
139 // Clone for another thread
140 let shared_clone = shared.clone();
141 let handle = thread::spawn(move || {
142 let mut value = 5;
143 let mutator = shared_clone;
144 mutator.apply(&mut value);
145 println!("In thread: 5 * 2 = {}", value);
146 value
147 });
148
149 // Use in main thread
150 let mut value = 3;
151 let mutator = shared;
152 mutator.apply(&mut value);
153 println!("Main thread: 3 * 2 = {}", value);
154
155 let thread_result = handle.join().unwrap();
156 println!("Thread result: {}\n", thread_result);
157
158 // ========================================================================
159 // Example 7: ArcMutator Composition (without consuming original mutator)
160 // ========================================================================
161 println!("Example 7: ArcMutator Composition (borrowing &self)");
162 println!("{}", "-".repeat(50));
163
164 let double = ArcMutator::new(|x: &mut i32| *x *= 2);
165 let add_ten = ArcMutator::new(|x: &mut i32| *x += 10);
166
167 // Composition doesn't consume the original mutator
168 let pipeline1 = double.and_then(add_ten.clone());
169 let pipeline2 = add_ten.and_then(double.clone());
170
171 let mut value1 = 5;
172 let p1 = pipeline1;
173 p1.apply(&mut value1);
174 println!("pipeline1 (double then add): 5 -> {}", value1);
175
176 let mut value2 = 5;
177 let p2 = pipeline2;
178 p2.apply(&mut value2);
179 println!("pipeline2 (add then double): 5 -> {}", value2);
180
181 // double and add_ten are still available
182 let mut value3 = 10;
183 let d = double;
184 d.apply(&mut value3);
185 println!("Original double still available: 10 -> {}\n", value3);
186
187 // ========================================================================
188 // Example 8: RcMutator - Single-threaded Sharing
189 // ========================================================================
190 println!("Example 8: RcMutator - Single-threaded Sharing");
191 println!("{}", "-".repeat(50));
192
193 let rc_mutator = RcMutator::new(|x: &mut i32| *x *= 2);
194
195 // Clone multiple copies
196 let clone1 = rc_mutator.clone();
197 let clone2 = rc_mutator.clone();
198
199 let mut value1 = 5;
200 let c1 = clone1;
201 c1.apply(&mut value1);
202 println!("clone1: 5 -> {}", value1);
203
204 let mut value2 = 3;
205 let c2 = clone2;
206 c2.apply(&mut value2);
207 println!("clone2: 3 -> {}", value2);
208
209 let mut value3 = 7;
210 let c3 = rc_mutator;
211 c3.apply(&mut value3);
212 println!("Original: 7 -> {}\n", value3);
213
214 // ========================================================================
215 // Example 9: RcMutator Composition (borrowing &self)
216 // ========================================================================
217 println!("Example 9: RcMutator Composition (borrowing &self)");
218 println!("{}", "-".repeat(50));
219
220 let double = RcMutator::new(|x: &mut i32| *x *= 2);
221 let add_ten = RcMutator::new(|x: &mut i32| *x += 10);
222
223 let pipeline1 = double.and_then(add_ten.clone());
224 let pipeline2 = add_ten.and_then(double.clone());
225
226 let mut value1 = 5;
227 let p1 = pipeline1;
228 p1.apply(&mut value1);
229 println!("pipeline1 (double then add): 5 -> {}", value1);
230
231 let mut value2 = 5;
232 let p2 = pipeline2;
233 p2.apply(&mut value2);
234 println!("pipeline2 (add then double): 5 -> {}\n", value2);
235
236 // ========================================================================
237 // Example 10: Unified Mutator trait
238 // ========================================================================
239 println!("Example 10: Unified Mutator trait");
240 println!("{}", "-".repeat(50));
241
242 fn apply_to_all<M: Mutator<i32>>(mutator: &mut M, values: &mut [i32]) {
243 for value in values.iter_mut() {
244 mutator.apply(value);
245 }
246 }
247
248 let mut values1 = vec![1, 2, 3, 4, 5];
249 let mut box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
250 println!("Using BoxMutator: {:?}", values1);
251 apply_to_all(&mut box_mut, &mut values1);
252 println!("Result: {:?}", values1);
253
254 let mut values2 = vec![1, 2, 3, 4, 5];
255 let mut arc_mut = ArcMutator::new(|x: &mut i32| *x *= 2);
256 println!("Using ArcMutator: {:?}", values2);
257 apply_to_all(&mut arc_mut, &mut values2);
258 println!("Result: {:?}", values2);
259
260 let mut values3 = vec![1, 2, 3, 4, 5];
261 let mut rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
262 println!("Using RcMutator: {:?}", values3);
263 apply_to_all(&mut rc_mut, &mut values3);
264 println!("Result: {:?}", values3);
265
266 let mut values4 = vec![1, 2, 3, 4, 5];
267 let mut closure = |x: &mut i32| *x *= 2;
268 println!("Using closure: {:?}", values4);
269 apply_to_all(&mut closure, &mut values4);
270 println!("Result: {:?}\n", values4);
271
272 // ========================================================================
273 // Example 11: Complex Data Processing Pipeline
274 // ========================================================================
275 println!("Example 11: Complex Data Processing Pipeline");
276 println!("{}", "-".repeat(50));
277
278 let pipeline = BoxMutator::new(|x: &mut i32| {
279 // Validation: clamp to 0-100
280 *x = (*x).clamp(0, 100);
281 })
282 .and_then(|x: &mut i32| {
283 // Normalization: scale to 0-10
284 *x /= 10;
285 })
286 .and_then(|x: &mut i32| {
287 // Transformation: square
288 *x = *x * *x;
289 });
290
291 let mut value1 = -50;
292 pipeline.apply(&mut value1);
293 println!("-50 -> {}", value1);
294
295 let mut value2 = 200;
296 pipeline.apply(&mut value2);
297 println!("200 -> {}", value2);
298
299 let mut value3 = 30;
300 pipeline.apply(&mut value3);
301 println!("30 -> {}\n", value3);
302
303 // ========================================================================
304 // Example 12: String Processing
305 // ========================================================================
306 println!("Example 12: String Processing");
307 println!("{}", "-".repeat(50));
308
309 let string_processor = BoxMutator::new(|s: &mut String| s.retain(|c| !c.is_whitespace()))
310 .and_then(|s: &mut String| *s = s.to_lowercase())
311 .and_then(|s: &mut String| s.push_str("!!!"));
312
313 let mut text = String::from("Hello World");
314 println!("Original: {}", text);
315 string_processor.apply(&mut text);
316 println!("After processing: {}\n", text);
317
318 // ========================================================================
319 // Example 13: Type Conversion
320 // ========================================================================
321 println!("Example 13: Type Conversion");
322 println!("{}", "-".repeat(50));
323
324 // Closure -> BoxMutator
325 let closure = |x: &mut i32| *x *= 2;
326 let box_mut = closure.into_box();
327 let mut value = 5;
328 box_mut.apply(&mut value);
329 println!("Closure -> BoxMutator: 5 -> {}", value);
330
331 // Closure -> RcMutator
332 let closure = |x: &mut i32| *x *= 2;
333 let rc_mut = closure.into_rc();
334 let mut value = 5;
335 rc_mut.apply(&mut value);
336 println!("Closure -> RcMutator: 5 -> {}", value);
337
338 // Closure -> ArcMutator
339 let closure = |x: &mut i32| *x *= 2;
340 let arc_mut = closure.into_arc();
341 let mut value = 5;
342 arc_mut.apply(&mut value);
343 println!("Closure -> ArcMutator: 5 -> {}", value);
344
345 // BoxMutator -> RcMutator
346 let box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
347 let rc_mut = box_mut.into_rc();
348 let mut value = 5;
349 rc_mut.apply(&mut value);
350 println!("BoxMutator -> RcMutator: 5 -> {}", value);
351
352 // RcMutator -> BoxMutator
353 let rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
354 let box_mut = rc_mut.into_box();
355 let mut value = 5;
356 box_mut.apply(&mut value);
357 println!("RcMutator -> BoxMutator: 5 -> {}\n", value);
358
359 // ========================================================================
360 // Example 14: Custom Types
361 // ========================================================================
362 println!("Example 14: Custom Types");
363 println!("{}", "-".repeat(50));
364
365 #[derive(Debug, Clone)]
366 struct Point {
367 x: i32,
368 y: i32,
369 }
370
371 let processor = BoxMutator::new(|p: &mut Point| p.x *= 2)
372 .and_then(|p: &mut Point| p.y *= 2)
373 .and_then(|p: &mut Point| p.x += p.y);
374
375 let mut point = Point { x: 3, y: 4 };
376 println!("Original point: {:?}", point);
377 processor.apply(&mut point);
378 println!("After processing: {:?}\n", point);
379
380 println!("=== All Examples Completed ===");
381}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?
27fn main() {
28 println!("=== Mutator Demo ===\n");
29
30 // ========================================================================
31 // Example 1: BoxMutator Basic Usage
32 // ========================================================================
33 println!("Example 1: BoxMutator Basic Usage");
34 println!("{}", "-".repeat(50));
35
36 let mutator = BoxMutator::new(|x: &mut i32| {
37 *x *= 2;
38 });
39 let mut value = 5;
40 println!("Initial value: {}", value);
41 mutator.apply(&mut value);
42 println!("After BoxMutator execution: {}\n", value);
43
44 // ========================================================================
45 // Example 2: BoxMutator Method Chaining
46 // ========================================================================
47 println!("Example 2: BoxMutator Method Chaining");
48 println!("{}", "-".repeat(50));
49
50 let chained = BoxMutator::new(|x: &mut i32| {
51 *x *= 2; // multiply by 2
52 })
53 .and_then(|x: &mut i32| {
54 *x += 10; // add 10
55 })
56 .and_then(|x: &mut i32| {
57 *x = *x * *x; // square
58 });
59
60 let mut value = 5;
61 println!("Initial value: {}", value);
62 chained.apply(&mut value);
63 println!("Result: {} (5 * 2 + 10 = 20, 20 * 20 = 400)\n", value);
64
65 // ========================================================================
66 // Example 3: Closure Extension Methods
67 // ========================================================================
68 println!("Example 3: Direct Use of Closure Extension Methods");
69 println!("{}", "-".repeat(50));
70
71 let closure_chain = (|x: &mut i32| *x *= 2).and_then(|x: &mut i32| *x += 10);
72
73 let mut value = 5;
74 println!("Initial value: {}", value);
75 closure_chain.apply(&mut value);
76 println!("Result: {} (5 * 2 + 10 = 20)\n", value);
77
78 // ========================================================================
79 // Example 4: BoxMutator Factory Methods
80 // ========================================================================
81 println!("Example 4: BoxMutator Factory Methods");
82 println!("{}", "-".repeat(50));
83
84 // noop
85 let noop = BoxMutator::<i32>::noop();
86 let mut value = 42;
87 println!("Before noop: {}", value);
88 noop.apply(&mut value);
89 println!("After noop: {} (unchanged)\n", value);
90
91 // ========================================================================
92 // Example 5: Conditional Mutator
93 // ========================================================================
94 println!("Example 5: Conditional Mutator");
95 println!("{}", "-".repeat(50));
96
97 // when (conditional execution)
98 let increment_if_positive = BoxMutator::new(|x: &mut i32| *x += 1).when(|x: &i32| *x > 0);
99
100 let mut positive = 5;
101 let mut negative = -5;
102 println!(
103 "Before when - positive: {}, negative: {}",
104 positive, negative
105 );
106 increment_if_positive.apply(&mut positive);
107 increment_if_positive.apply(&mut negative);
108 println!(
109 "After when - positive: {}, negative: {}\n",
110 positive, negative
111 );
112
113 // when().or_else() (conditional branching)
114 let adjust = BoxMutator::new(|x: &mut i32| *x *= 2)
115 .when(|x: &i32| *x > 0)
116 .or_else(|x: &mut i32| *x = -*x);
117
118 let mut positive = 10;
119 let mut negative = -10;
120 println!(
121 "Before when().or_else() - positive: {}, negative: {}",
122 positive, negative
123 );
124 adjust.apply(&mut positive);
125 adjust.apply(&mut negative);
126 println!(
127 "After when().or_else() - positive: {}, negative: {}\n",
128 positive, negative
129 );
130
131 // ========================================================================
132 // Example 6: ArcMutator - Multi-threaded Sharing
133 // ========================================================================
134 println!("Example 6: ArcMutator - Multi-threaded Sharing");
135 println!("{}", "-".repeat(50));
136
137 let shared = ArcMutator::new(|x: &mut i32| *x *= 2);
138
139 // Clone for another thread
140 let shared_clone = shared.clone();
141 let handle = thread::spawn(move || {
142 let mut value = 5;
143 let mutator = shared_clone;
144 mutator.apply(&mut value);
145 println!("In thread: 5 * 2 = {}", value);
146 value
147 });
148
149 // Use in main thread
150 let mut value = 3;
151 let mutator = shared;
152 mutator.apply(&mut value);
153 println!("Main thread: 3 * 2 = {}", value);
154
155 let thread_result = handle.join().unwrap();
156 println!("Thread result: {}\n", thread_result);
157
158 // ========================================================================
159 // Example 7: ArcMutator Composition (without consuming original mutator)
160 // ========================================================================
161 println!("Example 7: ArcMutator Composition (borrowing &self)");
162 println!("{}", "-".repeat(50));
163
164 let double = ArcMutator::new(|x: &mut i32| *x *= 2);
165 let add_ten = ArcMutator::new(|x: &mut i32| *x += 10);
166
167 // Composition doesn't consume the original mutator
168 let pipeline1 = double.and_then(add_ten.clone());
169 let pipeline2 = add_ten.and_then(double.clone());
170
171 let mut value1 = 5;
172 let p1 = pipeline1;
173 p1.apply(&mut value1);
174 println!("pipeline1 (double then add): 5 -> {}", value1);
175
176 let mut value2 = 5;
177 let p2 = pipeline2;
178 p2.apply(&mut value2);
179 println!("pipeline2 (add then double): 5 -> {}", value2);
180
181 // double and add_ten are still available
182 let mut value3 = 10;
183 let d = double;
184 d.apply(&mut value3);
185 println!("Original double still available: 10 -> {}\n", value3);
186
187 // ========================================================================
188 // Example 8: RcMutator - Single-threaded Sharing
189 // ========================================================================
190 println!("Example 8: RcMutator - Single-threaded Sharing");
191 println!("{}", "-".repeat(50));
192
193 let rc_mutator = RcMutator::new(|x: &mut i32| *x *= 2);
194
195 // Clone multiple copies
196 let clone1 = rc_mutator.clone();
197 let clone2 = rc_mutator.clone();
198
199 let mut value1 = 5;
200 let c1 = clone1;
201 c1.apply(&mut value1);
202 println!("clone1: 5 -> {}", value1);
203
204 let mut value2 = 3;
205 let c2 = clone2;
206 c2.apply(&mut value2);
207 println!("clone2: 3 -> {}", value2);
208
209 let mut value3 = 7;
210 let c3 = rc_mutator;
211 c3.apply(&mut value3);
212 println!("Original: 7 -> {}\n", value3);
213
214 // ========================================================================
215 // Example 9: RcMutator Composition (borrowing &self)
216 // ========================================================================
217 println!("Example 9: RcMutator Composition (borrowing &self)");
218 println!("{}", "-".repeat(50));
219
220 let double = RcMutator::new(|x: &mut i32| *x *= 2);
221 let add_ten = RcMutator::new(|x: &mut i32| *x += 10);
222
223 let pipeline1 = double.and_then(add_ten.clone());
224 let pipeline2 = add_ten.and_then(double.clone());
225
226 let mut value1 = 5;
227 let p1 = pipeline1;
228 p1.apply(&mut value1);
229 println!("pipeline1 (double then add): 5 -> {}", value1);
230
231 let mut value2 = 5;
232 let p2 = pipeline2;
233 p2.apply(&mut value2);
234 println!("pipeline2 (add then double): 5 -> {}\n", value2);
235
236 // ========================================================================
237 // Example 10: Unified Mutator trait
238 // ========================================================================
239 println!("Example 10: Unified Mutator trait");
240 println!("{}", "-".repeat(50));
241
242 fn apply_to_all<M: Mutator<i32>>(mutator: &mut M, values: &mut [i32]) {
243 for value in values.iter_mut() {
244 mutator.apply(value);
245 }
246 }
247
248 let mut values1 = vec![1, 2, 3, 4, 5];
249 let mut box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
250 println!("Using BoxMutator: {:?}", values1);
251 apply_to_all(&mut box_mut, &mut values1);
252 println!("Result: {:?}", values1);
253
254 let mut values2 = vec![1, 2, 3, 4, 5];
255 let mut arc_mut = ArcMutator::new(|x: &mut i32| *x *= 2);
256 println!("Using ArcMutator: {:?}", values2);
257 apply_to_all(&mut arc_mut, &mut values2);
258 println!("Result: {:?}", values2);
259
260 let mut values3 = vec![1, 2, 3, 4, 5];
261 let mut rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
262 println!("Using RcMutator: {:?}", values3);
263 apply_to_all(&mut rc_mut, &mut values3);
264 println!("Result: {:?}", values3);
265
266 let mut values4 = vec![1, 2, 3, 4, 5];
267 let mut closure = |x: &mut i32| *x *= 2;
268 println!("Using closure: {:?}", values4);
269 apply_to_all(&mut closure, &mut values4);
270 println!("Result: {:?}\n", values4);
271
272 // ========================================================================
273 // Example 11: Complex Data Processing Pipeline
274 // ========================================================================
275 println!("Example 11: Complex Data Processing Pipeline");
276 println!("{}", "-".repeat(50));
277
278 let pipeline = BoxMutator::new(|x: &mut i32| {
279 // Validation: clamp to 0-100
280 *x = (*x).clamp(0, 100);
281 })
282 .and_then(|x: &mut i32| {
283 // Normalization: scale to 0-10
284 *x /= 10;
285 })
286 .and_then(|x: &mut i32| {
287 // Transformation: square
288 *x = *x * *x;
289 });
290
291 let mut value1 = -50;
292 pipeline.apply(&mut value1);
293 println!("-50 -> {}", value1);
294
295 let mut value2 = 200;
296 pipeline.apply(&mut value2);
297 println!("200 -> {}", value2);
298
299 let mut value3 = 30;
300 pipeline.apply(&mut value3);
301 println!("30 -> {}\n", value3);
302
303 // ========================================================================
304 // Example 12: String Processing
305 // ========================================================================
306 println!("Example 12: String Processing");
307 println!("{}", "-".repeat(50));
308
309 let string_processor = BoxMutator::new(|s: &mut String| s.retain(|c| !c.is_whitespace()))
310 .and_then(|s: &mut String| *s = s.to_lowercase())
311 .and_then(|s: &mut String| s.push_str("!!!"));
312
313 let mut text = String::from("Hello World");
314 println!("Original: {}", text);
315 string_processor.apply(&mut text);
316 println!("After processing: {}\n", text);
317
318 // ========================================================================
319 // Example 13: Type Conversion
320 // ========================================================================
321 println!("Example 13: Type Conversion");
322 println!("{}", "-".repeat(50));
323
324 // Closure -> BoxMutator
325 let closure = |x: &mut i32| *x *= 2;
326 let box_mut = closure.into_box();
327 let mut value = 5;
328 box_mut.apply(&mut value);
329 println!("Closure -> BoxMutator: 5 -> {}", value);
330
331 // Closure -> RcMutator
332 let closure = |x: &mut i32| *x *= 2;
333 let rc_mut = closure.into_rc();
334 let mut value = 5;
335 rc_mut.apply(&mut value);
336 println!("Closure -> RcMutator: 5 -> {}", value);
337
338 // Closure -> ArcMutator
339 let closure = |x: &mut i32| *x *= 2;
340 let arc_mut = closure.into_arc();
341 let mut value = 5;
342 arc_mut.apply(&mut value);
343 println!("Closure -> ArcMutator: 5 -> {}", value);
344
345 // BoxMutator -> RcMutator
346 let box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
347 let rc_mut = box_mut.into_rc();
348 let mut value = 5;
349 rc_mut.apply(&mut value);
350 println!("BoxMutator -> RcMutator: 5 -> {}", value);
351
352 // RcMutator -> BoxMutator
353 let rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
354 let box_mut = rc_mut.into_box();
355 let mut value = 5;
356 box_mut.apply(&mut value);
357 println!("RcMutator -> BoxMutator: 5 -> {}\n", value);
358
359 // ========================================================================
360 // Example 14: Custom Types
361 // ========================================================================
362 println!("Example 14: Custom Types");
363 println!("{}", "-".repeat(50));
364
365 #[derive(Debug, Clone)]
366 struct Point {
367 x: i32,
368 y: i32,
369 }
370
371 let processor = BoxMutator::new(|p: &mut Point| p.x *= 2)
372 .and_then(|p: &mut Point| p.y *= 2)
373 .and_then(|p: &mut Point| p.x += p.y);
374
375 let mut point = Point { x: 3, y: 4 };
376 println!("Original point: {:?}", point);
377 processor.apply(&mut point);
378 println!("After processing: {:?}\n", point);
379
380 println!("=== All Examples Completed ===");
381}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.