Skip to main content

Mutator

Trait Mutator 

Source
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>, and RcMutator<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 (&self not &mut self)
  • Unified Interface: All mutator types share the same mutate method signature
  • Automatic Implementation: Closures automatically implement this trait
  • Type Conversions: Easy conversion between ownership models
  • Generic Programming: Write functions that work with any mutator type

§Examples

§Generic Mutator Function

use qubit_function::{Mutator, BoxMutator, ArcMutator};

fn apply_mutator<M: Mutator<i32>>(
    mutator: &mut M,
    value: i32
) -> i32 {
    let mut val = value;
    mutator.apply(&mut val);
    val
}

// Works with any mutator type
let mut box_mut = BoxMutator::new(|x: &mut i32| *x *= 2);
assert_eq!(apply_mutator(&mut box_mut, 5), 10);

let mut arc_mut = ArcMutator::new(|x: &mut i32| *x *= 2);
assert_eq!(apply_mutator(&mut arc_mut, 5), 10);

let mut closure = |x: &mut i32| *x *= 2;
assert_eq!(apply_mutator(&mut closure, 5), 10);

§Type Conversion

use qubit_function::Mutator;

let closure = |x: &mut i32| *x *= 2;

// Convert to different ownership models
let box_mutator = closure.into_box();
// let rc_mutator = closure.into_rc();  // closure moved
// let arc_mutator = closure.into_arc(); // closure moved

§Author

Haixing Hu

Required Methods§

Source

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§

Source

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

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

fn into_arc(self) -> ArcMutator<T>
where Self: Sized + Send + Sync + 'static,

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

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]);
Source

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);
Source

fn to_box(&self) -> BoxMutator<T>
where Self: Sized + Clone + 'static,

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.

Source

fn to_rc(&self) -> RcMutator<T>
where Self: Sized + Clone + 'static,

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.

Source

fn to_arc(&self) -> ArcMutator<T>
where Self: Sized + Clone + Send + Sync + 'static,

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.

Source

fn to_fn(&self) -> impl Fn(&mut T)
where Self: Sized + Clone + 'static,

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.

Source

fn to_once(&self) -> BoxMutatorOnce<T>
where Self: Sized + Clone + 'static,

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.

Implementors§

Source§

impl<T> Mutator<T> for ArcConditionalMutator<T>

Source§

impl<T> Mutator<T> for ArcMutator<T>

Source§

impl<T> Mutator<T> for BoxConditionalMutator<T>

Source§

impl<T> Mutator<T> for BoxMutator<T>

Source§

impl<T> Mutator<T> for RcConditionalMutator<T>

Source§

impl<T> Mutator<T> for RcMutator<T>

Source§

impl<T, F> Mutator<T> for F
where F: Fn(&mut T),