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