Mutator

Trait Mutator 

Source
pub trait Mutator<T> {
    // Required method
    fn mutate(&mut self, value: &mut T);

    // Provided methods
    fn into_box(self) -> BoxMutator<T>
       where Self: Sized + 'static,
             T: 'static { ... }
    fn into_rc(self) -> RcMutator<T>
       where Self: Sized + 'static,
             T: 'static { ... }
    fn into_arc(self) -> ArcMutator<T>
       where Self: Sized + Send + 'static,
             T: Send + 'static { ... }
    fn into_fn(self) -> impl FnMut(&mut T)
       where Self: Sized + 'static,
             T: 'static { ... }
    fn to_box(&self) -> BoxMutator<T>
       where Self: Sized + Clone + 'static,
             T: 'static { ... }
    fn to_rc(&self) -> RcMutator<T>
       where Self: Sized + Clone + 'static,
             T: 'static { ... }
    fn to_arc(&self) -> ArcMutator<T>
       where Self: Sized + Clone + Send + 'static,
             T: Send + 'static { ... }
    fn to_fn(&self) -> impl FnMut(&mut T)
       where Self: Sized + Clone + 'static,
             T: 'static { ... }
}
Expand description

Mutator trait - Unified mutator interface

Defines the core behavior of all mutator types. Performs operations that accept a mutable reference and modify the input value (not just side effects).

This trait is automatically implemented by:

  • All closures implementing FnMut(&mut T)
  • BoxMutator<T>, ArcMutator<T>, and RcMutator<T>

§Design Rationale

The trait provides a unified abstraction over different ownership models, allowing generic code to work with any mutator type. Type conversion methods (into_box, into_arc, into_rc) enable flexible ownership transitions based on usage requirements.

§Features

  • Unified Interface: All mutator types share the same mutate method signature
  • Automatic Implementation: Closures automatically implement this trait with zero overhead
  • Type Conversions: Easy conversion between ownership models
  • Generic Programming: Write functions that work with any mutator type

§Examples

§Generic Mutator Function

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

fn apply_mutator<M: Mutator<i32>>(
    mutator: &mut M,
    value: i32
) -> i32 {
    let mut val = value;
    mutator.mutate(&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 prism3_function::Mutator;

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

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

§Author

Haixing Hu

Required Methods§

Source

fn mutate(&mut self, value: &mut T)

Performs the mutation operation

Executes an operation on the given mutable reference. The operation typically modifies the input value or produces side effects.

§Parameters
  • value - A mutable reference to the value to be mutated
§Examples
use prism3_function::{Mutator, BoxMutator};

let mut mutator = BoxMutator::new(|x: &mut i32| *x *= 2);
let mut value = 5;
mutator.mutate(&mut value);
assert_eq!(value, 10);

Provided Methods§

Source

fn into_box(self) -> BoxMutator<T>
where Self: Sized + 'static, T: '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 prism3_function::Mutator;

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

fn into_rc(self) -> RcMutator<T>
where Self: Sized + 'static, T: '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 prism3_function::Mutator;

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

fn into_arc(self) -> ArcMutator<T>
where Self: Sized + Send + 'static, T: Send + '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 prism3_function::Mutator;

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

fn into_fn(self) -> impl FnMut(&mut T)
where Self: Sized + 'static, T: 'static,

Consume the mutator and return an FnMut(&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 FnMut(&mut T) which forwards to the original mutator.

§Examples
use prism3_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 to_box(&self) -> BoxMutator<T>
where Self: Sized + Clone + 'static, T: '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, T: '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 + 'static, T: Send + 'static,

Create a non-consuming ArcMutator<T> that forwards to self.

The default implementation clones self (requires Clone + Send) 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 FnMut(&mut T)
where Self: Sized + Clone + 'static, T: 'static,

Create a boxed FnMut(&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 FnMut(&mut T) which forwards to the original mutator.

Implementors§

Source§

impl<T> Mutator<T> for ArcConditionalMutator<T>
where T: Send + 'static,

Source§

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

Source§

impl<T> Mutator<T> for BoxConditionalMutator<T>
where T: 'static,

Source§

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

Source§

impl<T> Mutator<T> for RcConditionalMutator<T>
where T: 'static,

Source§

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

Source§

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