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!("Before when - positive: {}, negative: {}", positive, negative);
103 increment_if_positive.apply(&mut positive);
104 increment_if_positive.apply(&mut negative);
105 println!("After when - positive: {}, negative: {}\n", positive, negative);
106
107 // when().or_else() (conditional branching)
108 let adjust = BoxMutator::new(|x: &mut i32| *x *= 2)
109 .when(|x: &i32| *x > 0)
110 .or_else(|x: &mut i32| *x = -*x);
111
112 let mut positive = 10;
113 let mut negative = -10;
114 println!(
115 "Before when().or_else() - positive: {}, negative: {}",
116 positive, negative
117 );
118 adjust.apply(&mut positive);
119 adjust.apply(&mut negative);
120 println!(
121 "After when().or_else() - positive: {}, negative: {}\n",
122 positive, negative
123 );
124
125 // ========================================================================
126 // Example 6: ArcMutator - Multi-threaded Sharing
127 // ========================================================================
128 println!("Example 6: ArcMutator - Multi-threaded Sharing");
129 println!("{}", "-".repeat(50));
130
131 let shared = ArcMutator::new(|x: &mut i32| *x *= 2);
132
133 // Clone for another thread
134 let shared_clone = shared.clone();
135 let handle = thread::spawn(move || {
136 let mut value = 5;
137 let mutator = shared_clone;
138 mutator.apply(&mut value);
139 println!("In thread: 5 * 2 = {}", value);
140 value
141 });
142
143 // Use in main thread
144 let mut value = 3;
145 let mutator = shared;
146 mutator.apply(&mut value);
147 println!("Main thread: 3 * 2 = {}", value);
148
149 let thread_result = handle.join().expect("thread should not panic");
150 println!("Thread result: {}\n", thread_result);
151
152 // ========================================================================
153 // Example 7: ArcMutator Composition (without consuming original mutator)
154 // ========================================================================
155 println!("Example 7: ArcMutator Composition (borrowing &self)");
156 println!("{}", "-".repeat(50));
157
158 let double = ArcMutator::new(|x: &mut i32| *x *= 2);
159 let add_ten = ArcMutator::new(|x: &mut i32| *x += 10);
160
161 // Composition doesn't consume the original mutator
162 let pipeline1 = double.and_then(add_ten.clone());
163 let pipeline2 = add_ten.and_then(double.clone());
164
165 let mut value1 = 5;
166 let p1 = pipeline1;
167 p1.apply(&mut value1);
168 println!("pipeline1 (double then add): 5 -> {}", value1);
169
170 let mut value2 = 5;
171 let p2 = pipeline2;
172 p2.apply(&mut value2);
173 println!("pipeline2 (add then double): 5 -> {}", value2);
174
175 // double and add_ten are still available
176 let mut value3 = 10;
177 let d = double;
178 d.apply(&mut value3);
179 println!("Original double still available: 10 -> {}\n", value3);
180
181 // ========================================================================
182 // Example 8: RcMutator - Single-threaded Sharing
183 // ========================================================================
184 println!("Example 8: RcMutator - Single-threaded Sharing");
185 println!("{}", "-".repeat(50));
186
187 let rc_mutator = RcMutator::new(|x: &mut i32| *x *= 2);
188
189 // Clone multiple copies
190 let clone1 = rc_mutator.clone();
191 let clone2 = rc_mutator.clone();
192
193 let mut value1 = 5;
194 let c1 = clone1;
195 c1.apply(&mut value1);
196 println!("clone1: 5 -> {}", value1);
197
198 let mut value2 = 3;
199 let c2 = clone2;
200 c2.apply(&mut value2);
201 println!("clone2: 3 -> {}", value2);
202
203 let mut value3 = 7;
204 let c3 = rc_mutator;
205 c3.apply(&mut value3);
206 println!("Original: 7 -> {}\n", value3);
207
208 // ========================================================================
209 // Example 9: RcMutator Composition (borrowing &self)
210 // ========================================================================
211 println!("Example 9: RcMutator Composition (borrowing &self)");
212 println!("{}", "-".repeat(50));
213
214 let double = RcMutator::new(|x: &mut i32| *x *= 2);
215 let add_ten = RcMutator::new(|x: &mut i32| *x += 10);
216
217 let pipeline1 = double.and_then(add_ten.clone());
218 let pipeline2 = add_ten.and_then(double.clone());
219
220 let mut value1 = 5;
221 let p1 = pipeline1;
222 p1.apply(&mut value1);
223 println!("pipeline1 (double then add): 5 -> {}", value1);
224
225 let mut value2 = 5;
226 let p2 = pipeline2;
227 p2.apply(&mut value2);
228 println!("pipeline2 (add then double): 5 -> {}\n", value2);
229
230 // ========================================================================
231 // Example 10: Unified Mutator trait
232 // ========================================================================
233 println!("Example 10: Unified Mutator trait");
234 println!("{}", "-".repeat(50));
235
236 fn apply_to_all<M: Mutator<i32>>(mutator: &mut M, values: &mut [i32]) {
237 for value in values.iter_mut() {
238 mutator.apply(value);
239 }
240 }
241
242 let mut values1 = vec![1, 2, 3, 4, 5];
243 let mut box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
244 println!("Using BoxMutator: {:?}", values1);
245 apply_to_all(&mut box_mut, &mut values1);
246 println!("Result: {:?}", values1);
247
248 let mut values2 = vec![1, 2, 3, 4, 5];
249 let mut arc_mut = ArcMutator::new(|x: &mut i32| *x *= 2);
250 println!("Using ArcMutator: {:?}", values2);
251 apply_to_all(&mut arc_mut, &mut values2);
252 println!("Result: {:?}", values2);
253
254 let mut values3 = vec![1, 2, 3, 4, 5];
255 let mut rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
256 println!("Using RcMutator: {:?}", values3);
257 apply_to_all(&mut rc_mut, &mut values3);
258 println!("Result: {:?}", values3);
259
260 let mut values4 = vec![1, 2, 3, 4, 5];
261 let mut closure = |x: &mut i32| *x *= 2;
262 println!("Using closure: {:?}", values4);
263 apply_to_all(&mut closure, &mut values4);
264 println!("Result: {:?}\n", values4);
265
266 // ========================================================================
267 // Example 11: Complex Data Processing Pipeline
268 // ========================================================================
269 println!("Example 11: Complex Data Processing Pipeline");
270 println!("{}", "-".repeat(50));
271
272 let pipeline = BoxMutator::new(|x: &mut i32| {
273 // Validation: clamp to 0-100
274 *x = (*x).clamp(0, 100);
275 })
276 .and_then(|x: &mut i32| {
277 // Normalization: scale to 0-10
278 *x /= 10;
279 })
280 .and_then(|x: &mut i32| {
281 // Transformation: square
282 *x = *x * *x;
283 });
284
285 let mut value1 = -50;
286 pipeline.apply(&mut value1);
287 println!("-50 -> {}", value1);
288
289 let mut value2 = 200;
290 pipeline.apply(&mut value2);
291 println!("200 -> {}", value2);
292
293 let mut value3 = 30;
294 pipeline.apply(&mut value3);
295 println!("30 -> {}\n", value3);
296
297 // ========================================================================
298 // Example 12: String Processing
299 // ========================================================================
300 println!("Example 12: String Processing");
301 println!("{}", "-".repeat(50));
302
303 let string_processor = BoxMutator::new(|s: &mut String| s.retain(|c| !c.is_whitespace()))
304 .and_then(|s: &mut String| *s = s.to_lowercase())
305 .and_then(|s: &mut String| s.push_str("!!!"));
306
307 let mut text = String::from("Hello World");
308 println!("Original: {}", text);
309 string_processor.apply(&mut text);
310 println!("After processing: {}\n", text);
311
312 // ========================================================================
313 // Example 13: Type Conversion
314 // ========================================================================
315 println!("Example 13: Type Conversion");
316 println!("{}", "-".repeat(50));
317
318 // Closure -> BoxMutator
319 let closure = |x: &mut i32| *x *= 2;
320 let box_mut = closure.into_box();
321 let mut value = 5;
322 box_mut.apply(&mut value);
323 println!("Closure -> BoxMutator: 5 -> {}", value);
324
325 // Closure -> RcMutator
326 let closure = |x: &mut i32| *x *= 2;
327 let rc_mut = closure.into_rc();
328 let mut value = 5;
329 rc_mut.apply(&mut value);
330 println!("Closure -> RcMutator: 5 -> {}", value);
331
332 // Closure -> ArcMutator
333 let closure = |x: &mut i32| *x *= 2;
334 let arc_mut = closure.into_arc();
335 let mut value = 5;
336 arc_mut.apply(&mut value);
337 println!("Closure -> ArcMutator: 5 -> {}", value);
338
339 // BoxMutator -> RcMutator
340 let box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
341 let rc_mut = box_mut.into_rc();
342 let mut value = 5;
343 rc_mut.apply(&mut value);
344 println!("BoxMutator -> RcMutator: 5 -> {}", value);
345
346 // RcMutator -> BoxMutator
347 let rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
348 let box_mut = rc_mut.into_box();
349 let mut value = 5;
350 box_mut.apply(&mut value);
351 println!("RcMutator -> BoxMutator: 5 -> {}\n", value);
352
353 // ========================================================================
354 // Example 14: Custom Types
355 // ========================================================================
356 println!("Example 14: Custom Types");
357 println!("{}", "-".repeat(50));
358
359 #[derive(Debug, Clone)]
360 struct Point {
361 x: i32,
362 y: i32,
363 }
364
365 let processor = BoxMutator::new(|p: &mut Point| p.x *= 2)
366 .and_then(|p: &mut Point| p.y *= 2)
367 .and_then(|p: &mut Point| p.x += p.y);
368
369 let mut point = Point { x: 3, y: 4 };
370 println!("Original point: {:?}", point);
371 processor.apply(&mut point);
372 println!("After processing: {:?}\n", point);
373
374 println!("=== All Examples Completed ===");
375}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!("Before when - positive: {}, negative: {}", positive, negative);
103 increment_if_positive.apply(&mut positive);
104 increment_if_positive.apply(&mut negative);
105 println!("After when - positive: {}, negative: {}\n", positive, negative);
106
107 // when().or_else() (conditional branching)
108 let adjust = BoxMutator::new(|x: &mut i32| *x *= 2)
109 .when(|x: &i32| *x > 0)
110 .or_else(|x: &mut i32| *x = -*x);
111
112 let mut positive = 10;
113 let mut negative = -10;
114 println!(
115 "Before when().or_else() - positive: {}, negative: {}",
116 positive, negative
117 );
118 adjust.apply(&mut positive);
119 adjust.apply(&mut negative);
120 println!(
121 "After when().or_else() - positive: {}, negative: {}\n",
122 positive, negative
123 );
124
125 // ========================================================================
126 // Example 6: ArcMutator - Multi-threaded Sharing
127 // ========================================================================
128 println!("Example 6: ArcMutator - Multi-threaded Sharing");
129 println!("{}", "-".repeat(50));
130
131 let shared = ArcMutator::new(|x: &mut i32| *x *= 2);
132
133 // Clone for another thread
134 let shared_clone = shared.clone();
135 let handle = thread::spawn(move || {
136 let mut value = 5;
137 let mutator = shared_clone;
138 mutator.apply(&mut value);
139 println!("In thread: 5 * 2 = {}", value);
140 value
141 });
142
143 // Use in main thread
144 let mut value = 3;
145 let mutator = shared;
146 mutator.apply(&mut value);
147 println!("Main thread: 3 * 2 = {}", value);
148
149 let thread_result = handle.join().expect("thread should not panic");
150 println!("Thread result: {}\n", thread_result);
151
152 // ========================================================================
153 // Example 7: ArcMutator Composition (without consuming original mutator)
154 // ========================================================================
155 println!("Example 7: ArcMutator Composition (borrowing &self)");
156 println!("{}", "-".repeat(50));
157
158 let double = ArcMutator::new(|x: &mut i32| *x *= 2);
159 let add_ten = ArcMutator::new(|x: &mut i32| *x += 10);
160
161 // Composition doesn't consume the original mutator
162 let pipeline1 = double.and_then(add_ten.clone());
163 let pipeline2 = add_ten.and_then(double.clone());
164
165 let mut value1 = 5;
166 let p1 = pipeline1;
167 p1.apply(&mut value1);
168 println!("pipeline1 (double then add): 5 -> {}", value1);
169
170 let mut value2 = 5;
171 let p2 = pipeline2;
172 p2.apply(&mut value2);
173 println!("pipeline2 (add then double): 5 -> {}", value2);
174
175 // double and add_ten are still available
176 let mut value3 = 10;
177 let d = double;
178 d.apply(&mut value3);
179 println!("Original double still available: 10 -> {}\n", value3);
180
181 // ========================================================================
182 // Example 8: RcMutator - Single-threaded Sharing
183 // ========================================================================
184 println!("Example 8: RcMutator - Single-threaded Sharing");
185 println!("{}", "-".repeat(50));
186
187 let rc_mutator = RcMutator::new(|x: &mut i32| *x *= 2);
188
189 // Clone multiple copies
190 let clone1 = rc_mutator.clone();
191 let clone2 = rc_mutator.clone();
192
193 let mut value1 = 5;
194 let c1 = clone1;
195 c1.apply(&mut value1);
196 println!("clone1: 5 -> {}", value1);
197
198 let mut value2 = 3;
199 let c2 = clone2;
200 c2.apply(&mut value2);
201 println!("clone2: 3 -> {}", value2);
202
203 let mut value3 = 7;
204 let c3 = rc_mutator;
205 c3.apply(&mut value3);
206 println!("Original: 7 -> {}\n", value3);
207
208 // ========================================================================
209 // Example 9: RcMutator Composition (borrowing &self)
210 // ========================================================================
211 println!("Example 9: RcMutator Composition (borrowing &self)");
212 println!("{}", "-".repeat(50));
213
214 let double = RcMutator::new(|x: &mut i32| *x *= 2);
215 let add_ten = RcMutator::new(|x: &mut i32| *x += 10);
216
217 let pipeline1 = double.and_then(add_ten.clone());
218 let pipeline2 = add_ten.and_then(double.clone());
219
220 let mut value1 = 5;
221 let p1 = pipeline1;
222 p1.apply(&mut value1);
223 println!("pipeline1 (double then add): 5 -> {}", value1);
224
225 let mut value2 = 5;
226 let p2 = pipeline2;
227 p2.apply(&mut value2);
228 println!("pipeline2 (add then double): 5 -> {}\n", value2);
229
230 // ========================================================================
231 // Example 10: Unified Mutator trait
232 // ========================================================================
233 println!("Example 10: Unified Mutator trait");
234 println!("{}", "-".repeat(50));
235
236 fn apply_to_all<M: Mutator<i32>>(mutator: &mut M, values: &mut [i32]) {
237 for value in values.iter_mut() {
238 mutator.apply(value);
239 }
240 }
241
242 let mut values1 = vec![1, 2, 3, 4, 5];
243 let mut box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
244 println!("Using BoxMutator: {:?}", values1);
245 apply_to_all(&mut box_mut, &mut values1);
246 println!("Result: {:?}", values1);
247
248 let mut values2 = vec![1, 2, 3, 4, 5];
249 let mut arc_mut = ArcMutator::new(|x: &mut i32| *x *= 2);
250 println!("Using ArcMutator: {:?}", values2);
251 apply_to_all(&mut arc_mut, &mut values2);
252 println!("Result: {:?}", values2);
253
254 let mut values3 = vec![1, 2, 3, 4, 5];
255 let mut rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
256 println!("Using RcMutator: {:?}", values3);
257 apply_to_all(&mut rc_mut, &mut values3);
258 println!("Result: {:?}", values3);
259
260 let mut values4 = vec![1, 2, 3, 4, 5];
261 let mut closure = |x: &mut i32| *x *= 2;
262 println!("Using closure: {:?}", values4);
263 apply_to_all(&mut closure, &mut values4);
264 println!("Result: {:?}\n", values4);
265
266 // ========================================================================
267 // Example 11: Complex Data Processing Pipeline
268 // ========================================================================
269 println!("Example 11: Complex Data Processing Pipeline");
270 println!("{}", "-".repeat(50));
271
272 let pipeline = BoxMutator::new(|x: &mut i32| {
273 // Validation: clamp to 0-100
274 *x = (*x).clamp(0, 100);
275 })
276 .and_then(|x: &mut i32| {
277 // Normalization: scale to 0-10
278 *x /= 10;
279 })
280 .and_then(|x: &mut i32| {
281 // Transformation: square
282 *x = *x * *x;
283 });
284
285 let mut value1 = -50;
286 pipeline.apply(&mut value1);
287 println!("-50 -> {}", value1);
288
289 let mut value2 = 200;
290 pipeline.apply(&mut value2);
291 println!("200 -> {}", value2);
292
293 let mut value3 = 30;
294 pipeline.apply(&mut value3);
295 println!("30 -> {}\n", value3);
296
297 // ========================================================================
298 // Example 12: String Processing
299 // ========================================================================
300 println!("Example 12: String Processing");
301 println!("{}", "-".repeat(50));
302
303 let string_processor = BoxMutator::new(|s: &mut String| s.retain(|c| !c.is_whitespace()))
304 .and_then(|s: &mut String| *s = s.to_lowercase())
305 .and_then(|s: &mut String| s.push_str("!!!"));
306
307 let mut text = String::from("Hello World");
308 println!("Original: {}", text);
309 string_processor.apply(&mut text);
310 println!("After processing: {}\n", text);
311
312 // ========================================================================
313 // Example 13: Type Conversion
314 // ========================================================================
315 println!("Example 13: Type Conversion");
316 println!("{}", "-".repeat(50));
317
318 // Closure -> BoxMutator
319 let closure = |x: &mut i32| *x *= 2;
320 let box_mut = closure.into_box();
321 let mut value = 5;
322 box_mut.apply(&mut value);
323 println!("Closure -> BoxMutator: 5 -> {}", value);
324
325 // Closure -> RcMutator
326 let closure = |x: &mut i32| *x *= 2;
327 let rc_mut = closure.into_rc();
328 let mut value = 5;
329 rc_mut.apply(&mut value);
330 println!("Closure -> RcMutator: 5 -> {}", value);
331
332 // Closure -> ArcMutator
333 let closure = |x: &mut i32| *x *= 2;
334 let arc_mut = closure.into_arc();
335 let mut value = 5;
336 arc_mut.apply(&mut value);
337 println!("Closure -> ArcMutator: 5 -> {}", value);
338
339 // BoxMutator -> RcMutator
340 let box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
341 let rc_mut = box_mut.into_rc();
342 let mut value = 5;
343 rc_mut.apply(&mut value);
344 println!("BoxMutator -> RcMutator: 5 -> {}", value);
345
346 // RcMutator -> BoxMutator
347 let rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
348 let box_mut = rc_mut.into_box();
349 let mut value = 5;
350 box_mut.apply(&mut value);
351 println!("RcMutator -> BoxMutator: 5 -> {}\n", value);
352
353 // ========================================================================
354 // Example 14: Custom Types
355 // ========================================================================
356 println!("Example 14: Custom Types");
357 println!("{}", "-".repeat(50));
358
359 #[derive(Debug, Clone)]
360 struct Point {
361 x: i32,
362 y: i32,
363 }
364
365 let processor = BoxMutator::new(|p: &mut Point| p.x *= 2)
366 .and_then(|p: &mut Point| p.y *= 2)
367 .and_then(|p: &mut Point| p.x += p.y);
368
369 let mut point = Point { x: 3, y: 4 };
370 println!("Original point: {:?}", point);
371 processor.apply(&mut point);
372 println!("After processing: {:?}\n", point);
373
374 println!("=== All Examples Completed ===");
375}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!("Before when - positive: {}, negative: {}", positive, negative);
103 increment_if_positive.apply(&mut positive);
104 increment_if_positive.apply(&mut negative);
105 println!("After when - positive: {}, negative: {}\n", positive, negative);
106
107 // when().or_else() (conditional branching)
108 let adjust = BoxMutator::new(|x: &mut i32| *x *= 2)
109 .when(|x: &i32| *x > 0)
110 .or_else(|x: &mut i32| *x = -*x);
111
112 let mut positive = 10;
113 let mut negative = -10;
114 println!(
115 "Before when().or_else() - positive: {}, negative: {}",
116 positive, negative
117 );
118 adjust.apply(&mut positive);
119 adjust.apply(&mut negative);
120 println!(
121 "After when().or_else() - positive: {}, negative: {}\n",
122 positive, negative
123 );
124
125 // ========================================================================
126 // Example 6: ArcMutator - Multi-threaded Sharing
127 // ========================================================================
128 println!("Example 6: ArcMutator - Multi-threaded Sharing");
129 println!("{}", "-".repeat(50));
130
131 let shared = ArcMutator::new(|x: &mut i32| *x *= 2);
132
133 // Clone for another thread
134 let shared_clone = shared.clone();
135 let handle = thread::spawn(move || {
136 let mut value = 5;
137 let mutator = shared_clone;
138 mutator.apply(&mut value);
139 println!("In thread: 5 * 2 = {}", value);
140 value
141 });
142
143 // Use in main thread
144 let mut value = 3;
145 let mutator = shared;
146 mutator.apply(&mut value);
147 println!("Main thread: 3 * 2 = {}", value);
148
149 let thread_result = handle.join().expect("thread should not panic");
150 println!("Thread result: {}\n", thread_result);
151
152 // ========================================================================
153 // Example 7: ArcMutator Composition (without consuming original mutator)
154 // ========================================================================
155 println!("Example 7: ArcMutator Composition (borrowing &self)");
156 println!("{}", "-".repeat(50));
157
158 let double = ArcMutator::new(|x: &mut i32| *x *= 2);
159 let add_ten = ArcMutator::new(|x: &mut i32| *x += 10);
160
161 // Composition doesn't consume the original mutator
162 let pipeline1 = double.and_then(add_ten.clone());
163 let pipeline2 = add_ten.and_then(double.clone());
164
165 let mut value1 = 5;
166 let p1 = pipeline1;
167 p1.apply(&mut value1);
168 println!("pipeline1 (double then add): 5 -> {}", value1);
169
170 let mut value2 = 5;
171 let p2 = pipeline2;
172 p2.apply(&mut value2);
173 println!("pipeline2 (add then double): 5 -> {}", value2);
174
175 // double and add_ten are still available
176 let mut value3 = 10;
177 let d = double;
178 d.apply(&mut value3);
179 println!("Original double still available: 10 -> {}\n", value3);
180
181 // ========================================================================
182 // Example 8: RcMutator - Single-threaded Sharing
183 // ========================================================================
184 println!("Example 8: RcMutator - Single-threaded Sharing");
185 println!("{}", "-".repeat(50));
186
187 let rc_mutator = RcMutator::new(|x: &mut i32| *x *= 2);
188
189 // Clone multiple copies
190 let clone1 = rc_mutator.clone();
191 let clone2 = rc_mutator.clone();
192
193 let mut value1 = 5;
194 let c1 = clone1;
195 c1.apply(&mut value1);
196 println!("clone1: 5 -> {}", value1);
197
198 let mut value2 = 3;
199 let c2 = clone2;
200 c2.apply(&mut value2);
201 println!("clone2: 3 -> {}", value2);
202
203 let mut value3 = 7;
204 let c3 = rc_mutator;
205 c3.apply(&mut value3);
206 println!("Original: 7 -> {}\n", value3);
207
208 // ========================================================================
209 // Example 9: RcMutator Composition (borrowing &self)
210 // ========================================================================
211 println!("Example 9: RcMutator Composition (borrowing &self)");
212 println!("{}", "-".repeat(50));
213
214 let double = RcMutator::new(|x: &mut i32| *x *= 2);
215 let add_ten = RcMutator::new(|x: &mut i32| *x += 10);
216
217 let pipeline1 = double.and_then(add_ten.clone());
218 let pipeline2 = add_ten.and_then(double.clone());
219
220 let mut value1 = 5;
221 let p1 = pipeline1;
222 p1.apply(&mut value1);
223 println!("pipeline1 (double then add): 5 -> {}", value1);
224
225 let mut value2 = 5;
226 let p2 = pipeline2;
227 p2.apply(&mut value2);
228 println!("pipeline2 (add then double): 5 -> {}\n", value2);
229
230 // ========================================================================
231 // Example 10: Unified Mutator trait
232 // ========================================================================
233 println!("Example 10: Unified Mutator trait");
234 println!("{}", "-".repeat(50));
235
236 fn apply_to_all<M: Mutator<i32>>(mutator: &mut M, values: &mut [i32]) {
237 for value in values.iter_mut() {
238 mutator.apply(value);
239 }
240 }
241
242 let mut values1 = vec![1, 2, 3, 4, 5];
243 let mut box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
244 println!("Using BoxMutator: {:?}", values1);
245 apply_to_all(&mut box_mut, &mut values1);
246 println!("Result: {:?}", values1);
247
248 let mut values2 = vec![1, 2, 3, 4, 5];
249 let mut arc_mut = ArcMutator::new(|x: &mut i32| *x *= 2);
250 println!("Using ArcMutator: {:?}", values2);
251 apply_to_all(&mut arc_mut, &mut values2);
252 println!("Result: {:?}", values2);
253
254 let mut values3 = vec![1, 2, 3, 4, 5];
255 let mut rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
256 println!("Using RcMutator: {:?}", values3);
257 apply_to_all(&mut rc_mut, &mut values3);
258 println!("Result: {:?}", values3);
259
260 let mut values4 = vec![1, 2, 3, 4, 5];
261 let mut closure = |x: &mut i32| *x *= 2;
262 println!("Using closure: {:?}", values4);
263 apply_to_all(&mut closure, &mut values4);
264 println!("Result: {:?}\n", values4);
265
266 // ========================================================================
267 // Example 11: Complex Data Processing Pipeline
268 // ========================================================================
269 println!("Example 11: Complex Data Processing Pipeline");
270 println!("{}", "-".repeat(50));
271
272 let pipeline = BoxMutator::new(|x: &mut i32| {
273 // Validation: clamp to 0-100
274 *x = (*x).clamp(0, 100);
275 })
276 .and_then(|x: &mut i32| {
277 // Normalization: scale to 0-10
278 *x /= 10;
279 })
280 .and_then(|x: &mut i32| {
281 // Transformation: square
282 *x = *x * *x;
283 });
284
285 let mut value1 = -50;
286 pipeline.apply(&mut value1);
287 println!("-50 -> {}", value1);
288
289 let mut value2 = 200;
290 pipeline.apply(&mut value2);
291 println!("200 -> {}", value2);
292
293 let mut value3 = 30;
294 pipeline.apply(&mut value3);
295 println!("30 -> {}\n", value3);
296
297 // ========================================================================
298 // Example 12: String Processing
299 // ========================================================================
300 println!("Example 12: String Processing");
301 println!("{}", "-".repeat(50));
302
303 let string_processor = BoxMutator::new(|s: &mut String| s.retain(|c| !c.is_whitespace()))
304 .and_then(|s: &mut String| *s = s.to_lowercase())
305 .and_then(|s: &mut String| s.push_str("!!!"));
306
307 let mut text = String::from("Hello World");
308 println!("Original: {}", text);
309 string_processor.apply(&mut text);
310 println!("After processing: {}\n", text);
311
312 // ========================================================================
313 // Example 13: Type Conversion
314 // ========================================================================
315 println!("Example 13: Type Conversion");
316 println!("{}", "-".repeat(50));
317
318 // Closure -> BoxMutator
319 let closure = |x: &mut i32| *x *= 2;
320 let box_mut = closure.into_box();
321 let mut value = 5;
322 box_mut.apply(&mut value);
323 println!("Closure -> BoxMutator: 5 -> {}", value);
324
325 // Closure -> RcMutator
326 let closure = |x: &mut i32| *x *= 2;
327 let rc_mut = closure.into_rc();
328 let mut value = 5;
329 rc_mut.apply(&mut value);
330 println!("Closure -> RcMutator: 5 -> {}", value);
331
332 // Closure -> ArcMutator
333 let closure = |x: &mut i32| *x *= 2;
334 let arc_mut = closure.into_arc();
335 let mut value = 5;
336 arc_mut.apply(&mut value);
337 println!("Closure -> ArcMutator: 5 -> {}", value);
338
339 // BoxMutator -> RcMutator
340 let box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
341 let rc_mut = box_mut.into_rc();
342 let mut value = 5;
343 rc_mut.apply(&mut value);
344 println!("BoxMutator -> RcMutator: 5 -> {}", value);
345
346 // RcMutator -> BoxMutator
347 let rc_mut = RcMutator::new(|x: &mut i32| *x *= 2);
348 let box_mut = rc_mut.into_box();
349 let mut value = 5;
350 box_mut.apply(&mut value);
351 println!("RcMutator -> BoxMutator: 5 -> {}\n", value);
352
353 // ========================================================================
354 // Example 14: Custom Types
355 // ========================================================================
356 println!("Example 14: Custom Types");
357 println!("{}", "-".repeat(50));
358
359 #[derive(Debug, Clone)]
360 struct Point {
361 x: i32,
362 y: i32,
363 }
364
365 let processor = BoxMutator::new(|p: &mut Point| p.x *= 2)
366 .and_then(|p: &mut Point| p.y *= 2)
367 .and_then(|p: &mut Point| p.x += p.y);
368
369 let mut point = Point { x: 3, y: 4 };
370 println!("Original point: {:?}", point);
371 processor.apply(&mut point);
372 println!("After processing: {:?}\n", point);
373
374 println!("=== All Examples Completed ===");
375}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.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".