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

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 320)
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}
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 327)
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}
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 334)
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}
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.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

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),