RcMutator

Struct RcMutator 

Source
pub struct RcMutator<T> { /* private fields */ }
Expand description

RcMutator struct

A mutator implementation based on Rc<RefCell<dyn FnMut(&mut T)>> for single-threaded shared ownership scenarios. This type allows multiple references to the same mutator without the overhead of thread safety.

§Features

  • Shared Ownership: Cloneable via Rc, multiple owners allowed
  • Single-Threaded: Not thread-safe, cannot be sent across threads
  • Interior Mutability: Uses RefCell for runtime borrow checking
  • Mutable State: Can modify captured environment via FnMut
  • Chainable: Method chaining via &self (non-consuming)
  • Performance: More efficient than ArcMutator (no locking)

§Use Cases

Choose RcMutator when:

  • The mutator needs to be shared within a single thread
  • Thread safety is not required
  • Performance is important (avoiding lock overhead)

§Examples

use prism3_function::{Mutator, RcMutator};

let mutator = RcMutator::new(|x: &mut i32| *x *= 2);
let clone = mutator.clone();

let mut value = 5;
let mut m = mutator;
m.mutate(&mut value);
assert_eq!(value, 10);

§Author

Haixing Hu

Implementations§

Source§

impl<T> RcMutator<T>
where T: 'static,

Source

pub fn new<F>(f: F) -> Self
where F: FnMut(&mut T) + 'static,

Creates a new RcMutator

§Parameters
  • f - The closure to wrap
§Returns

Returns a new RcMutator<T> instance

§Examples
use prism3_function::{Mutator, RcMutator};

let mutator = RcMutator::new(|x: &mut i32| *x += 1);
let mut value = 5;
let mut m = mutator;
m.mutate(&mut value);
assert_eq!(value, 6);
Examples found in repository?
examples/mutator_demo.rs (line 186)
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

pub fn noop() -> Self

Creates a no-op mutator

Returns a mutator that performs no operation.

§Returns

Returns a no-op mutator

§Examples
use prism3_function::{Mutator, RcMutator};

let noop = RcMutator::<i32>::noop();
let mut value = 42;
let mut m = noop;
m.mutate(&mut value);
assert_eq!(value, 42); // Value unchanged
Source

pub fn and_then(&self, next: &RcMutator<T>) -> RcMutator<T>

Chains another RcMutator in sequence

Returns a new mutator that first executes the current operation, then executes the next operation. Borrows &self, does not consume the original mutator.

§Parameters
  • next - The mutator to execute after the current operation
§Returns

Returns a new composed RcMutator<T>

§Examples
use prism3_function::{Mutator, RcMutator};

let first = RcMutator::new(|x: &mut i32| *x *= 2);
let second = RcMutator::new(|x: &mut i32| *x += 10);

let chained = first.and_then(&second);

// first and second are still usable
let mut value = 5;
let mut m = chained;
m.mutate(&mut value);
assert_eq!(value, 20); // (5 * 2) + 10
Examples found in repository?
examples/mutator_demo.rs (line 216)
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

pub fn when<P>(&self, predicate: P) -> RcConditionalMutator<T>
where P: Predicate<T> + 'static,

Creates a conditional mutator (single-threaded shared version)

Returns a mutator that only executes when a predicate is satisfied.

§Parameters
  • predicate - The condition to check. Note: This parameter is passed by value and will transfer ownership. If you need to preserve the original predicate, clone it first (if it implements Clone). Can be:
    • A closure: |x: &T| -> bool
    • A function pointer: fn(&T) -> bool
    • An RcPredicate<T>
    • A BoxPredicate<T>
    • Any type implementing Predicate<T>
§Returns

Returns RcConditionalMutator<T>

§Examples
use prism3_function::{Mutator, RcMutator};

let mutator = RcMutator::new(|x: &mut i32| *x *= 2);
let conditional = mutator.when(|x: &i32| *x > 0);

let conditional_clone = conditional.clone();

let mut positive = 5;
let mut m = conditional;
m.mutate(&mut positive);
assert_eq!(positive, 10);

Trait Implementations§

Source§

impl<T> Clone for RcMutator<T>

Source§

fn clone(&self) -> Self

Clones the RcMutator

Creates a new RcMutator that shares the underlying function with the original instance.

1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

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

Source§

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

Performs the mutation operation Read more
Source§

fn into_box(self) -> BoxMutator<T>
where T: 'static,

Convert this mutator into a BoxMutator<T>. Read more
Source§

fn into_rc(self) -> RcMutator<T>
where T: 'static,

Convert this mutator into an RcMutator<T>. Read more
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. Read more
Source§

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

Create a non-consuming BoxMutator<T> that forwards to self. Read more
Source§

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

Create a non-consuming RcMutator<T> that forwards to self. Read more
Source§

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

Create a boxed FnMut(&mut T) closure that forwards to self. Read more
Source§

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

Convert this mutator into an ArcMutator<T>. Read more
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. Read more
Source§

impl<T> MutatorOnce<T> for RcMutator<T>
where T: 'static,

Source§

fn mutate_once(self, value: &mut T)

Performs the one-time mutation operation

Consumes self and executes the mutation operation on the given mutable reference. This is a one-time operation that cannot be called again.

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

let mutator = RcMutator::new(|x: &mut i32| *x *= 2);
let mut value = 5;
mutator.mutate_once(&mut value);
assert_eq!(value, 10);
Source§

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

Converts to BoxMutatorOnce (consuming)

Consumes self and returns an owned BoxMutatorOnce<T>. The underlying function is extracted from the Rc<RefCell<>> wrapper.

§Returns

Returns a BoxMutatorOnce<T> that forwards to the original mutator.

Source§

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

Converts to a consuming closure FnOnce(&mut T)

Consumes self and returns a closure that, when invoked, calls the mutation operation.

§Returns

A closure implementing FnOnce(&mut T) which forwards to the original mutator.

Source§

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

Non-consuming adapter to BoxMutatorOnce

Creates a BoxMutatorOnce<T> that does not consume self. This method clones the underlying Rc reference and creates a new boxed mutator.

§Returns

A BoxMutatorOnce<T> that forwards to a clone of self.

Source§

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

Non-consuming adapter to a callable FnOnce(&mut T)

Returns a closure that does not consume self. This method clones the underlying Rc reference for the captured closure.

§Returns

A closure implementing FnOnce(&mut T) which forwards to a clone of the original mutator.

Auto Trait Implementations§

§

impl<T> Freeze for RcMutator<T>

§

impl<T> !RefUnwindSafe for RcMutator<T>

§

impl<T> !Send for RcMutator<T>

§

impl<T> !Sync for RcMutator<T>

§

impl<T> Unpin for RcMutator<T>

§

impl<T> !UnwindSafe for RcMutator<T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.