pub struct BoxMutatorOnce<T> { /* private fields */ }Expand description
BoxMutatorOnce struct
A one-time mutator implementation based on Box<dyn FnOnce(&mut T)> for
single ownership scenarios. This is the only MutatorOnce implementation type
because FnOnce conflicts with shared ownership semantics.
§Features
- Single Ownership: Not cloneable, consumes self on use
- Zero Overhead: No reference counting or locking
- Move Semantics: Can capture and move variables
- Method Chaining: Compose multiple operations via
and_then
§Use Cases
Choose BoxMutatorOnce when:
- Need to store FnOnce closures (with moved captured variables)
- One-time resource transfer operations
- Post-initialization callbacks
- Complex operations requiring ownership transfer
§Performance
BoxMutatorOnce performance characteristics:
- No reference counting overhead
- No lock acquisition or runtime borrow checking
- Direct function call through vtable
- Minimal memory footprint (single pointer)
§Why No Arc/Rc Variants?
FnOnce can only be called once, which conflicts with Arc/Rc shared ownership semantics:
- Arc/Rc implies multiple owners might need to call
- FnOnce is consumed after calling, cannot be called again
- This semantic incompatibility makes Arc/Rc variants meaningless
§Examples
§Basic Usage
use prism3_function::{MutatorOnce, BoxMutatorOnce};
let data = vec![1, 2, 3];
let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
x.extend(data); // Move data
});
let mut target = vec![0];
mutator.mutate_once(&mut target);
assert_eq!(target, vec![0, 1, 2, 3]);§Method Chaining
use prism3_function::{MutatorOnce, BoxMutatorOnce};
let data1 = vec![1, 2];
let data2 = vec![3, 4];
let chained = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
x.extend(data1);
})
.and_then(move |x: &mut Vec<i32>| {
x.extend(data2);
});
let mut target = vec![0];
chained.mutate_once(&mut target);
assert_eq!(target, vec![0, 1, 2, 3, 4]);§Author
Haixing Hu
Implementations§
Source§impl<T> BoxMutatorOnce<T>where
T: 'static,
impl<T> BoxMutatorOnce<T>where
T: 'static,
Sourcepub fn new<F>(f: F) -> Self
pub fn new<F>(f: F) -> Self
Creates a new BoxMutatorOnce
§Parameters
f- The closure to wrap
§Returns
Returns a new BoxMutatorOnce<T> instance
§Examples
use prism3_function::{MutatorOnce, BoxMutatorOnce};
let data = String::from("world");
let mutator = BoxMutatorOnce::new(move |x: &mut String| {
x.push_str(" ");
x.push_str(&data); // Move data
});
let mut target = String::from("hello");
mutator.mutate_once(&mut target);
assert_eq!(target, "hello world");Examples found in repository?
15fn main() {
16 println!("=== MutatorOnce Examples ===\n");
17
18 // 1. Basic usage: moving captured variables
19 println!("1. Basic usage: moving captured variables");
20 let data = vec![1, 2, 3];
21 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
22 println!(" Adding data: {:?}", data);
23 x.extend(data);
24 });
25
26 let mut target = vec![0];
27 mutator.mutate_once(&mut target);
28 println!(" Result: {:?}\n", target);
29
30 // 2. Method chaining: combining multiple operations
31 println!("2. Method chaining: combining multiple operations");
32 let prefix = vec![1, 2];
33 let middle = vec![3, 4];
34 let suffix = vec![5, 6];
35
36 let chained = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
37 println!(" Adding prefix: {:?}", prefix);
38 x.extend(prefix);
39 })
40 .and_then(move |x: &mut Vec<i32>| {
41 println!(" Adding middle: {:?}", middle);
42 x.extend(middle);
43 })
44 .and_then(move |x: &mut Vec<i32>| {
45 println!(" Adding suffix: {:?}", suffix);
46 x.extend(suffix);
47 });
48
49 let mut result = vec![0];
50 chained.mutate_once(&mut result);
51 println!(" Result: {:?}\n", result);
52
53 // 3. Initializer pattern
54 println!("3. Initializer pattern");
55
56 struct Initializer {
57 name: String,
58 on_complete: Option<BoxMutatorOnce<Vec<String>>>,
59 }
60
61 impl Initializer {
62 fn new<F>(name: impl Into<String>, callback: F) -> Self
63 where
64 F: FnOnce(&mut Vec<String>) + 'static,
65 {
66 Self {
67 name: name.into(),
68 on_complete: Some(BoxMutatorOnce::new(callback)),
69 }
70 }
71
72 fn run(mut self, data: &mut Vec<String>) {
73 println!(" Initializer '{}' is running", self.name);
74 data.push(format!("Initialized by {}", self.name));
75
76 if let Some(callback) = self.on_complete.take() {
77 println!(" Executing completion callback");
78 callback.mutate_once(data);
79 }
80 }
81 }
82
83 let extra = vec!["extra1".to_string(), "extra2".to_string()];
84 let init = Initializer::new("MainInit", move |values| {
85 println!(" Adding extra data in callback: {:?}", extra);
86 values.extend(extra);
87 });
88
89 let mut config = Vec::new();
90 init.run(&mut config);
91 println!(" Final config: {:?}\n", config);
92
93 // 4. String builder pattern
94 println!("4. String builder pattern");
95 let greeting = String::from("Hello, ");
96 let name = String::from("Alice");
97 let punctuation = String::from("!");
98
99 let builder = BoxMutatorOnce::new(move |s: &mut String| {
100 println!(" Adding greeting: {}", greeting);
101 s.insert_str(0, &greeting);
102 })
103 .and_then(move |s: &mut String| {
104 println!(" Adding name: {}", name);
105 s.push_str(&name);
106 })
107 .and_then(move |s: &mut String| {
108 println!(" Adding punctuation: {}", punctuation);
109 s.push_str(&punctuation);
110 })
111 .and_then(|s: &mut String| {
112 println!(" Converting to uppercase");
113 *s = s.to_uppercase();
114 });
115
116 let mut message = String::new();
117 builder.mutate_once(&mut message);
118 println!(" Final message: {}\n", message);
119
120 // 5. Direct closure usage
121 println!("5. Direct closure usage");
122 let data1 = vec![10, 20];
123 let data2 = vec![30, 40];
124
125 let chained_closure = (move |x: &mut Vec<i32>| {
126 println!(" Step 1: Adding {:?}", data1);
127 x.extend(data1);
128 })
129 .and_then(move |x: &mut Vec<i32>| {
130 println!(" Step 2: Adding {:?}", data2);
131 x.extend(data2);
132 })
133 .and_then(|x: &mut Vec<i32>| {
134 println!(" Step 3: Multiplying each element by 2");
135 x.iter_mut().for_each(|n| *n *= 2);
136 });
137
138 let mut values = vec![0];
139 chained_closure.mutate_once(&mut values);
140 println!(" Result: {:?}\n", values);
141
142 // 6. Resource transfer scenario
143 println!("6. Resource transfer scenario");
144 let large_data = vec![1; 10];
145 println!(
146 " Preparing to transfer large data (length: {})",
147 large_data.len()
148 );
149
150 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
151 println!(" Transferring data (moving, not cloning)");
152 x.extend(large_data); // large_data is moved, not cloned
153 });
154
155 let mut container = Vec::new();
156 mutator.mutate_once(&mut container);
157 println!(" Data length in container: {}\n", container.len());
158
159 // 7. Generic function usage
160 println!("7. Generic function usage");
161
162 fn apply_transformation<M: MutatorOnce<Vec<i32>>>(mutator: M, initial: Vec<i32>) -> Vec<i32> {
163 let mut val = initial;
164 mutator.mutate_once(&mut val);
165 val
166 }
167
168 let data = vec![100, 200, 300];
169 let result = apply_transformation(
170 move |x: &mut Vec<i32>| {
171 println!(" Adding in generic function: {:?}", data);
172 x.extend(data);
173 },
174 vec![0],
175 );
176 println!(" Result: {:?}\n", result);
177
178 // 8. Configuration builder
179 println!("8. Configuration builder");
180
181 struct Config {
182 options: Vec<String>,
183 }
184
185 impl Config {
186 fn new() -> Self {
187 Self {
188 options: Vec::new(),
189 }
190 }
191
192 fn with_defaults(mut self) -> Self {
193 println!(" Adding default options");
194 self.options.push("default1".to_string());
195 self.options.push("default2".to_string());
196 self
197 }
198
199 fn customize<F>(mut self, customizer: F) -> Self
200 where
201 F: FnOnce(&mut Vec<String>) + 'static,
202 {
203 println!(" Applying custom configuration");
204 customizer.mutate_once(&mut self.options);
205 self
206 }
207
208 fn build(self) -> Self {
209 println!(" Configuration build completed");
210 self
211 }
212 }
213
214 let custom_opts = vec!["custom1".to_string(), "custom2".to_string()];
215 let config = Config::new()
216 .with_defaults()
217 .customize(move |opts| {
218 println!(" Adding custom options: {:?}", custom_opts);
219 opts.extend(custom_opts);
220 })
221 .build();
222
223 println!(" Final options: {:?}\n", config.options);
224
225 println!("=== Examples completed ===");
226}More examples
16fn main() {
17 println!("=== MutatorOnce Conditional Execution Examples ===\n");
18
19 // 1. Basic conditional execution - when condition is satisfied
20 println!("1. Basic conditional execution - when condition is satisfied");
21 let data = vec![1, 2, 3];
22 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
23 println!(" Extending vector with data: {:?}", data);
24 x.extend(data);
25 });
26 let conditional = mutator.when(|x: &Vec<i32>| {
27 println!(" Checking condition: !x.is_empty()");
28 !x.is_empty()
29 });
30
31 let mut target = vec![0];
32 println!(" Initial: {:?}", target);
33 conditional.mutate_once(&mut target);
34 println!(" Result: {:?}\n", target);
35
36 // 2. Conditional execution - when condition is not satisfied
37 println!("2. Conditional execution - when condition is not satisfied");
38 let data = vec![4, 5, 6];
39 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
40 println!(" This should not be executed");
41 x.extend(data);
42 });
43 let conditional = mutator.when(|x: &Vec<i32>| {
44 println!(" Checking condition: x.len() > 10");
45 x.len() > 10
46 });
47
48 let mut target = vec![0];
49 println!(" Initial: {:?}", target);
50 conditional.mutate_once(&mut target);
51 println!(" Result: {:?} (unchanged)\n", target);
52
53 // 3. Using BoxPredicate
54 println!("3. Using BoxPredicate");
55 let pred = BoxPredicate::new(|x: &Vec<i32>| {
56 println!(" Predicate: checking if vector is not empty");
57 !x.is_empty()
58 });
59 let data = vec![7, 8, 9];
60 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
61 println!(" Adding data: {:?}", data);
62 x.extend(data);
63 });
64 let conditional = mutator.when(pred);
65
66 let mut target = vec![0];
67 println!(" Initial: {:?}", target);
68 conditional.mutate_once(&mut target);
69 println!(" Result: {:?}\n", target);
70
71 // 4. Using composed predicate
72 println!("4. Using composed predicate");
73 let pred = (|x: &Vec<i32>| {
74 println!(" Condition 1: !x.is_empty()");
75 !x.is_empty()
76 })
77 .and(|x: &Vec<i32>| {
78 println!(" Condition 2: x.len() < 10");
79 x.len() < 10
80 });
81 let data = vec![10, 11, 12];
82 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
83 println!(" Adding data: {:?}", data);
84 x.extend(data);
85 });
86 let conditional = mutator.when(pred);
87
88 let mut target = vec![0];
89 println!(" Initial: {:?}", target);
90 conditional.mutate_once(&mut target);
91 println!(" Result: {:?}\n", target);
92
93 // 5. If-then-else with or_else - when branch
94 println!("5. If-then-else with or_else - when branch");
95 let data1 = vec![1, 2, 3];
96 let data2 = vec![99];
97 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
98 println!(" When branch: adding {:?}", data1);
99 x.extend(data1);
100 })
101 .when(|x: &Vec<i32>| {
102 println!(" Checking: !x.is_empty()");
103 !x.is_empty()
104 })
105 .or_else(move |x: &mut Vec<i32>| {
106 println!(" Else branch: adding {:?}", data2);
107 x.extend(data2);
108 });
109
110 let mut target = vec![0];
111 println!(" Initial: {:?}", target);
112 mutator.mutate_once(&mut target);
113 println!(" Result: {:?}\n", target);
114
115 // 6. If-then-else with or_else - else branch
116 println!("6. If-then-else with or_else - else branch");
117 let data1 = vec![4, 5, 6];
118 let data2 = vec![99];
119 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
120 println!(" When branch: adding {:?}", data1);
121 x.extend(data1);
122 })
123 .when(|x: &Vec<i32>| {
124 println!(" Checking: x.is_empty()");
125 x.is_empty()
126 })
127 .or_else(move |x: &mut Vec<i32>| {
128 println!(" Else branch: adding {:?}", data2);
129 x.extend(data2);
130 });
131
132 let mut target = vec![0];
133 println!(" Initial: {:?}", target);
134 mutator.mutate_once(&mut target);
135 println!(" Result: {:?}\n", target);
136
137 // 7. Conditional with integers
138 println!("7. Conditional with integers");
139 let mutator = BoxMutatorOnce::new(|x: &mut i32| {
140 println!(" Multiplying by 2");
141 *x *= 2;
142 })
143 .when(|x: &i32| {
144 println!(" Checking: *x > 0");
145 *x > 0
146 });
147
148 let mut positive = 5;
149 println!(" Initial (positive): {}", positive);
150 mutator.mutate_once(&mut positive);
151 println!(" Result: {}\n", positive);
152
153 // 8. Conditional with integers - not executed
154 println!("8. Conditional with integers - not executed");
155 let mutator = BoxMutatorOnce::new(|x: &mut i32| {
156 println!(" This should not be executed");
157 *x *= 2;
158 })
159 .when(|x: &i32| {
160 println!(" Checking: *x > 0");
161 *x > 0
162 });
163
164 let mut negative = -5;
165 println!(" Initial (negative): {}", negative);
166 mutator.mutate_once(&mut negative);
167 println!(" Result: {} (unchanged)\n", negative);
168
169 // 9. Chaining conditional mutators
170 println!("9. Chaining conditional mutators");
171 let data1 = vec![1, 2];
172 let cond1 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
173 println!(" First mutator: adding {:?}", data1);
174 x.extend(data1);
175 })
176 .when(|x: &Vec<i32>| {
177 println!(" First condition: !x.is_empty()");
178 !x.is_empty()
179 });
180
181 let data2 = vec![3, 4];
182 let cond2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
183 println!(" Second mutator: adding {:?}", data2);
184 x.extend(data2);
185 })
186 .when(|x: &Vec<i32>| {
187 println!(" Second condition: x.len() < 10");
188 x.len() < 10
189 });
190
191 let chained = cond1.and_then(cond2);
192
193 let mut target = vec![0];
194 println!(" Initial: {:?}", target);
195 chained.mutate_once(&mut target);
196 println!(" Result: {:?}\n", target);
197
198 // 10. Complex conditional chain
199 println!("10. Complex conditional chain");
200 let data1 = vec![1, 2];
201 let data2 = vec![99];
202 let data3 = vec![5, 6];
203
204 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
205 println!(" When branch: adding {:?}", data1);
206 x.extend(data1);
207 })
208 .when(|x: &Vec<i32>| {
209 println!(" Checking: !x.is_empty()");
210 !x.is_empty()
211 })
212 .or_else(move |x: &mut Vec<i32>| {
213 println!(" Else branch: adding {:?}", data2);
214 x.extend(data2);
215 })
216 .and_then(move |x: &mut Vec<i32>| {
217 println!(" Final step: adding {:?}", data3);
218 x.extend(data3);
219 });
220
221 let mut target = vec![0];
222 println!(" Initial: {:?}", target);
223 mutator.mutate_once(&mut target);
224 println!(" Result: {:?}\n", target);
225
226 // 11. Real-world scenario: data validation and processing
227 println!("11. Real-world scenario: data validation and processing");
228
229 struct DataProcessor {
230 on_valid: Option<BoxMutatorOnce<Vec<String>>>,
231 on_invalid: Option<BoxMutatorOnce<Vec<String>>>,
232 }
233
234 impl DataProcessor {
235 fn new<V, I>(on_valid: V, on_invalid: I) -> Self
236 where
237 V: FnOnce(&mut Vec<String>) + 'static,
238 I: FnOnce(&mut Vec<String>) + 'static,
239 {
240 Self {
241 on_valid: Some(BoxMutatorOnce::new(on_valid)),
242 on_invalid: Some(BoxMutatorOnce::new(on_invalid)),
243 }
244 }
245
246 fn process(mut self, data: &mut Vec<String>) {
247 let is_valid = !data.is_empty() && data.iter().all(|s| !s.is_empty());
248 println!(
249 " Data validation: {}",
250 if is_valid { "VALID" } else { "INVALID" }
251 );
252
253 if is_valid {
254 if let Some(callback) = self.on_valid.take() {
255 callback.mutate_once(data);
256 }
257 } else if let Some(callback) = self.on_invalid.take() {
258 callback.mutate_once(data);
259 }
260 }
261 }
262
263 let valid_suffix = vec!["processed".to_string()];
264 let invalid_marker = vec!["[INVALID]".to_string()];
265
266 let processor = DataProcessor::new(
267 move |data| {
268 println!(" Valid data callback: adding suffix");
269 data.extend(valid_suffix);
270 },
271 move |data| {
272 println!(" Invalid data callback: adding error marker");
273 data.clear();
274 data.extend(invalid_marker);
275 },
276 );
277
278 let mut valid_data = vec!["item1".to_string(), "item2".to_string()];
279 println!(" Processing valid data: {:?}", valid_data);
280 processor.process(&mut valid_data);
281 println!(" Result: {:?}\n", valid_data);
282
283 println!("=== Examples completed ===");
284}Sourcepub fn and_then<C>(self, next: C) -> Selfwhere
C: MutatorOnce<T> + 'static,
pub fn and_then<C>(self, next: C) -> Selfwhere
C: MutatorOnce<T> + 'static,
Chains another mutator in sequence
Returns a new mutator that first executes the current operation, then executes the next operation. Consumes self.
§Parameters
next- The mutator to execute after the current operation. Note: This parameter is passed by value and will transfer ownership. SinceBoxMutatorOncecannot be cloned, the parameter will be consumed. Can be:- A closure:
|x: &mut T| - A
BoxMutatorOnce<T> - Any type implementing
MutatorOnce<T>
- A closure:
§Returns
Returns a new composed BoxMutatorOnce<T>
§Examples
use prism3_function::{MutatorOnce, BoxMutatorOnce};
let data1 = vec![1, 2];
let data2 = vec![3, 4];
let data3 = vec![5, 6];
let chained = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
x.extend(data1);
})
.and_then(move |x: &mut Vec<i32>| {
x.extend(data2);
})
.and_then(move |x: &mut Vec<i32>| {
x.extend(data3);
});
let mut target = vec![0];
chained.mutate_once(&mut target);
assert_eq!(target, vec![0, 1, 2, 3, 4, 5, 6]);Examples found in repository?
15fn main() {
16 println!("=== MutatorOnce Examples ===\n");
17
18 // 1. Basic usage: moving captured variables
19 println!("1. Basic usage: moving captured variables");
20 let data = vec![1, 2, 3];
21 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
22 println!(" Adding data: {:?}", data);
23 x.extend(data);
24 });
25
26 let mut target = vec![0];
27 mutator.mutate_once(&mut target);
28 println!(" Result: {:?}\n", target);
29
30 // 2. Method chaining: combining multiple operations
31 println!("2. Method chaining: combining multiple operations");
32 let prefix = vec![1, 2];
33 let middle = vec![3, 4];
34 let suffix = vec![5, 6];
35
36 let chained = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
37 println!(" Adding prefix: {:?}", prefix);
38 x.extend(prefix);
39 })
40 .and_then(move |x: &mut Vec<i32>| {
41 println!(" Adding middle: {:?}", middle);
42 x.extend(middle);
43 })
44 .and_then(move |x: &mut Vec<i32>| {
45 println!(" Adding suffix: {:?}", suffix);
46 x.extend(suffix);
47 });
48
49 let mut result = vec![0];
50 chained.mutate_once(&mut result);
51 println!(" Result: {:?}\n", result);
52
53 // 3. Initializer pattern
54 println!("3. Initializer pattern");
55
56 struct Initializer {
57 name: String,
58 on_complete: Option<BoxMutatorOnce<Vec<String>>>,
59 }
60
61 impl Initializer {
62 fn new<F>(name: impl Into<String>, callback: F) -> Self
63 where
64 F: FnOnce(&mut Vec<String>) + 'static,
65 {
66 Self {
67 name: name.into(),
68 on_complete: Some(BoxMutatorOnce::new(callback)),
69 }
70 }
71
72 fn run(mut self, data: &mut Vec<String>) {
73 println!(" Initializer '{}' is running", self.name);
74 data.push(format!("Initialized by {}", self.name));
75
76 if let Some(callback) = self.on_complete.take() {
77 println!(" Executing completion callback");
78 callback.mutate_once(data);
79 }
80 }
81 }
82
83 let extra = vec!["extra1".to_string(), "extra2".to_string()];
84 let init = Initializer::new("MainInit", move |values| {
85 println!(" Adding extra data in callback: {:?}", extra);
86 values.extend(extra);
87 });
88
89 let mut config = Vec::new();
90 init.run(&mut config);
91 println!(" Final config: {:?}\n", config);
92
93 // 4. String builder pattern
94 println!("4. String builder pattern");
95 let greeting = String::from("Hello, ");
96 let name = String::from("Alice");
97 let punctuation = String::from("!");
98
99 let builder = BoxMutatorOnce::new(move |s: &mut String| {
100 println!(" Adding greeting: {}", greeting);
101 s.insert_str(0, &greeting);
102 })
103 .and_then(move |s: &mut String| {
104 println!(" Adding name: {}", name);
105 s.push_str(&name);
106 })
107 .and_then(move |s: &mut String| {
108 println!(" Adding punctuation: {}", punctuation);
109 s.push_str(&punctuation);
110 })
111 .and_then(|s: &mut String| {
112 println!(" Converting to uppercase");
113 *s = s.to_uppercase();
114 });
115
116 let mut message = String::new();
117 builder.mutate_once(&mut message);
118 println!(" Final message: {}\n", message);
119
120 // 5. Direct closure usage
121 println!("5. Direct closure usage");
122 let data1 = vec![10, 20];
123 let data2 = vec![30, 40];
124
125 let chained_closure = (move |x: &mut Vec<i32>| {
126 println!(" Step 1: Adding {:?}", data1);
127 x.extend(data1);
128 })
129 .and_then(move |x: &mut Vec<i32>| {
130 println!(" Step 2: Adding {:?}", data2);
131 x.extend(data2);
132 })
133 .and_then(|x: &mut Vec<i32>| {
134 println!(" Step 3: Multiplying each element by 2");
135 x.iter_mut().for_each(|n| *n *= 2);
136 });
137
138 let mut values = vec![0];
139 chained_closure.mutate_once(&mut values);
140 println!(" Result: {:?}\n", values);
141
142 // 6. Resource transfer scenario
143 println!("6. Resource transfer scenario");
144 let large_data = vec![1; 10];
145 println!(
146 " Preparing to transfer large data (length: {})",
147 large_data.len()
148 );
149
150 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
151 println!(" Transferring data (moving, not cloning)");
152 x.extend(large_data); // large_data is moved, not cloned
153 });
154
155 let mut container = Vec::new();
156 mutator.mutate_once(&mut container);
157 println!(" Data length in container: {}\n", container.len());
158
159 // 7. Generic function usage
160 println!("7. Generic function usage");
161
162 fn apply_transformation<M: MutatorOnce<Vec<i32>>>(mutator: M, initial: Vec<i32>) -> Vec<i32> {
163 let mut val = initial;
164 mutator.mutate_once(&mut val);
165 val
166 }
167
168 let data = vec![100, 200, 300];
169 let result = apply_transformation(
170 move |x: &mut Vec<i32>| {
171 println!(" Adding in generic function: {:?}", data);
172 x.extend(data);
173 },
174 vec![0],
175 );
176 println!(" Result: {:?}\n", result);
177
178 // 8. Configuration builder
179 println!("8. Configuration builder");
180
181 struct Config {
182 options: Vec<String>,
183 }
184
185 impl Config {
186 fn new() -> Self {
187 Self {
188 options: Vec::new(),
189 }
190 }
191
192 fn with_defaults(mut self) -> Self {
193 println!(" Adding default options");
194 self.options.push("default1".to_string());
195 self.options.push("default2".to_string());
196 self
197 }
198
199 fn customize<F>(mut self, customizer: F) -> Self
200 where
201 F: FnOnce(&mut Vec<String>) + 'static,
202 {
203 println!(" Applying custom configuration");
204 customizer.mutate_once(&mut self.options);
205 self
206 }
207
208 fn build(self) -> Self {
209 println!(" Configuration build completed");
210 self
211 }
212 }
213
214 let custom_opts = vec!["custom1".to_string(), "custom2".to_string()];
215 let config = Config::new()
216 .with_defaults()
217 .customize(move |opts| {
218 println!(" Adding custom options: {:?}", custom_opts);
219 opts.extend(custom_opts);
220 })
221 .build();
222
223 println!(" Final options: {:?}\n", config.options);
224
225 println!("=== Examples completed ===");
226}More examples
16fn main() {
17 println!("=== MutatorOnce Conditional Execution Examples ===\n");
18
19 // 1. Basic conditional execution - when condition is satisfied
20 println!("1. Basic conditional execution - when condition is satisfied");
21 let data = vec![1, 2, 3];
22 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
23 println!(" Extending vector with data: {:?}", data);
24 x.extend(data);
25 });
26 let conditional = mutator.when(|x: &Vec<i32>| {
27 println!(" Checking condition: !x.is_empty()");
28 !x.is_empty()
29 });
30
31 let mut target = vec![0];
32 println!(" Initial: {:?}", target);
33 conditional.mutate_once(&mut target);
34 println!(" Result: {:?}\n", target);
35
36 // 2. Conditional execution - when condition is not satisfied
37 println!("2. Conditional execution - when condition is not satisfied");
38 let data = vec![4, 5, 6];
39 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
40 println!(" This should not be executed");
41 x.extend(data);
42 });
43 let conditional = mutator.when(|x: &Vec<i32>| {
44 println!(" Checking condition: x.len() > 10");
45 x.len() > 10
46 });
47
48 let mut target = vec![0];
49 println!(" Initial: {:?}", target);
50 conditional.mutate_once(&mut target);
51 println!(" Result: {:?} (unchanged)\n", target);
52
53 // 3. Using BoxPredicate
54 println!("3. Using BoxPredicate");
55 let pred = BoxPredicate::new(|x: &Vec<i32>| {
56 println!(" Predicate: checking if vector is not empty");
57 !x.is_empty()
58 });
59 let data = vec![7, 8, 9];
60 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
61 println!(" Adding data: {:?}", data);
62 x.extend(data);
63 });
64 let conditional = mutator.when(pred);
65
66 let mut target = vec![0];
67 println!(" Initial: {:?}", target);
68 conditional.mutate_once(&mut target);
69 println!(" Result: {:?}\n", target);
70
71 // 4. Using composed predicate
72 println!("4. Using composed predicate");
73 let pred = (|x: &Vec<i32>| {
74 println!(" Condition 1: !x.is_empty()");
75 !x.is_empty()
76 })
77 .and(|x: &Vec<i32>| {
78 println!(" Condition 2: x.len() < 10");
79 x.len() < 10
80 });
81 let data = vec![10, 11, 12];
82 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
83 println!(" Adding data: {:?}", data);
84 x.extend(data);
85 });
86 let conditional = mutator.when(pred);
87
88 let mut target = vec![0];
89 println!(" Initial: {:?}", target);
90 conditional.mutate_once(&mut target);
91 println!(" Result: {:?}\n", target);
92
93 // 5. If-then-else with or_else - when branch
94 println!("5. If-then-else with or_else - when branch");
95 let data1 = vec![1, 2, 3];
96 let data2 = vec![99];
97 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
98 println!(" When branch: adding {:?}", data1);
99 x.extend(data1);
100 })
101 .when(|x: &Vec<i32>| {
102 println!(" Checking: !x.is_empty()");
103 !x.is_empty()
104 })
105 .or_else(move |x: &mut Vec<i32>| {
106 println!(" Else branch: adding {:?}", data2);
107 x.extend(data2);
108 });
109
110 let mut target = vec![0];
111 println!(" Initial: {:?}", target);
112 mutator.mutate_once(&mut target);
113 println!(" Result: {:?}\n", target);
114
115 // 6. If-then-else with or_else - else branch
116 println!("6. If-then-else with or_else - else branch");
117 let data1 = vec![4, 5, 6];
118 let data2 = vec![99];
119 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
120 println!(" When branch: adding {:?}", data1);
121 x.extend(data1);
122 })
123 .when(|x: &Vec<i32>| {
124 println!(" Checking: x.is_empty()");
125 x.is_empty()
126 })
127 .or_else(move |x: &mut Vec<i32>| {
128 println!(" Else branch: adding {:?}", data2);
129 x.extend(data2);
130 });
131
132 let mut target = vec![0];
133 println!(" Initial: {:?}", target);
134 mutator.mutate_once(&mut target);
135 println!(" Result: {:?}\n", target);
136
137 // 7. Conditional with integers
138 println!("7. Conditional with integers");
139 let mutator = BoxMutatorOnce::new(|x: &mut i32| {
140 println!(" Multiplying by 2");
141 *x *= 2;
142 })
143 .when(|x: &i32| {
144 println!(" Checking: *x > 0");
145 *x > 0
146 });
147
148 let mut positive = 5;
149 println!(" Initial (positive): {}", positive);
150 mutator.mutate_once(&mut positive);
151 println!(" Result: {}\n", positive);
152
153 // 8. Conditional with integers - not executed
154 println!("8. Conditional with integers - not executed");
155 let mutator = BoxMutatorOnce::new(|x: &mut i32| {
156 println!(" This should not be executed");
157 *x *= 2;
158 })
159 .when(|x: &i32| {
160 println!(" Checking: *x > 0");
161 *x > 0
162 });
163
164 let mut negative = -5;
165 println!(" Initial (negative): {}", negative);
166 mutator.mutate_once(&mut negative);
167 println!(" Result: {} (unchanged)\n", negative);
168
169 // 9. Chaining conditional mutators
170 println!("9. Chaining conditional mutators");
171 let data1 = vec![1, 2];
172 let cond1 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
173 println!(" First mutator: adding {:?}", data1);
174 x.extend(data1);
175 })
176 .when(|x: &Vec<i32>| {
177 println!(" First condition: !x.is_empty()");
178 !x.is_empty()
179 });
180
181 let data2 = vec![3, 4];
182 let cond2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
183 println!(" Second mutator: adding {:?}", data2);
184 x.extend(data2);
185 })
186 .when(|x: &Vec<i32>| {
187 println!(" Second condition: x.len() < 10");
188 x.len() < 10
189 });
190
191 let chained = cond1.and_then(cond2);
192
193 let mut target = vec![0];
194 println!(" Initial: {:?}", target);
195 chained.mutate_once(&mut target);
196 println!(" Result: {:?}\n", target);
197
198 // 10. Complex conditional chain
199 println!("10. Complex conditional chain");
200 let data1 = vec![1, 2];
201 let data2 = vec![99];
202 let data3 = vec![5, 6];
203
204 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
205 println!(" When branch: adding {:?}", data1);
206 x.extend(data1);
207 })
208 .when(|x: &Vec<i32>| {
209 println!(" Checking: !x.is_empty()");
210 !x.is_empty()
211 })
212 .or_else(move |x: &mut Vec<i32>| {
213 println!(" Else branch: adding {:?}", data2);
214 x.extend(data2);
215 })
216 .and_then(move |x: &mut Vec<i32>| {
217 println!(" Final step: adding {:?}", data3);
218 x.extend(data3);
219 });
220
221 let mut target = vec![0];
222 println!(" Initial: {:?}", target);
223 mutator.mutate_once(&mut target);
224 println!(" Result: {:?}\n", target);
225
226 // 11. Real-world scenario: data validation and processing
227 println!("11. Real-world scenario: data validation and processing");
228
229 struct DataProcessor {
230 on_valid: Option<BoxMutatorOnce<Vec<String>>>,
231 on_invalid: Option<BoxMutatorOnce<Vec<String>>>,
232 }
233
234 impl DataProcessor {
235 fn new<V, I>(on_valid: V, on_invalid: I) -> Self
236 where
237 V: FnOnce(&mut Vec<String>) + 'static,
238 I: FnOnce(&mut Vec<String>) + 'static,
239 {
240 Self {
241 on_valid: Some(BoxMutatorOnce::new(on_valid)),
242 on_invalid: Some(BoxMutatorOnce::new(on_invalid)),
243 }
244 }
245
246 fn process(mut self, data: &mut Vec<String>) {
247 let is_valid = !data.is_empty() && data.iter().all(|s| !s.is_empty());
248 println!(
249 " Data validation: {}",
250 if is_valid { "VALID" } else { "INVALID" }
251 );
252
253 if is_valid {
254 if let Some(callback) = self.on_valid.take() {
255 callback.mutate_once(data);
256 }
257 } else if let Some(callback) = self.on_invalid.take() {
258 callback.mutate_once(data);
259 }
260 }
261 }
262
263 let valid_suffix = vec!["processed".to_string()];
264 let invalid_marker = vec!["[INVALID]".to_string()];
265
266 let processor = DataProcessor::new(
267 move |data| {
268 println!(" Valid data callback: adding suffix");
269 data.extend(valid_suffix);
270 },
271 move |data| {
272 println!(" Invalid data callback: adding error marker");
273 data.clear();
274 data.extend(invalid_marker);
275 },
276 );
277
278 let mut valid_data = vec!["item1".to_string(), "item2".to_string()];
279 println!(" Processing valid data: {:?}", valid_data);
280 processor.process(&mut valid_data);
281 println!(" Result: {:?}\n", valid_data);
282
283 println!("=== Examples completed ===");
284}Sourcepub fn when<P>(self, predicate: P) -> BoxConditionalMutatorOnce<T>where
P: Predicate<T> + 'static,
pub fn when<P>(self, predicate: P) -> BoxConditionalMutatorOnce<T>where
P: Predicate<T> + 'static,
Creates a conditional mutator
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 implementsClone). Can be:- A closure:
|x: &T| -> bool - A function pointer:
fn(&T) -> bool - A
BoxPredicate<T> - An
RcPredicate<T> - An
ArcPredicate<T> - Any type implementing
Predicate<T>
- A closure:
§Returns
Returns BoxConditionalMutatorOnce<T>
§Examples
§Using a closure
use prism3_function::{MutatorOnce, BoxMutatorOnce};
let data = vec![1, 2, 3];
let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
x.extend(data);
});
let conditional = mutator.when(|x: &Vec<i32>| !x.is_empty());
let mut target = vec![0];
conditional.mutate_once(&mut target);
assert_eq!(target, vec![0, 1, 2, 3]);
let mut empty = Vec::new();
let data2 = vec![4, 5];
let mutator2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
x.extend(data2);
});
let conditional2 = mutator2.when(|x: &Vec<i32>| x.len() > 5);
conditional2.mutate_once(&mut empty);
assert_eq!(empty, Vec::<i32>::new()); // Unchanged§Preserving predicate with clone
use prism3_function::{MutatorOnce, BoxMutatorOnce, RcPredicate};
use prism3_function::predicate::Predicate;
let data = vec![1, 2, 3];
let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
x.extend(data);
});
let predicate = RcPredicate::new(|x: &Vec<i32>| !x.is_empty());
// Clone to preserve original predicate
let conditional = mutator.when(predicate.clone());
let mut target = vec![0];
conditional.mutate_once(&mut target);
assert_eq!(target, vec![0, 1, 2, 3]);
// Original predicate still usable
assert!(predicate.test(&vec![1, 2]));§Using composed predicate
use prism3_function::{MutatorOnce, BoxMutatorOnce};
use prism3_function::predicate::{Predicate, FnPredicateOps};
let pred = (|x: &Vec<i32>| !x.is_empty())
.and(|x: &Vec<i32>| x.len() < 10);
let data = vec![1, 2, 3];
let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
x.extend(data);
});
let conditional = mutator.when(pred);
let mut target = vec![0];
conditional.mutate_once(&mut target);
assert_eq!(target, vec![0, 1, 2, 3]);Examples found in repository?
16fn main() {
17 println!("=== MutatorOnce Conditional Execution Examples ===\n");
18
19 // 1. Basic conditional execution - when condition is satisfied
20 println!("1. Basic conditional execution - when condition is satisfied");
21 let data = vec![1, 2, 3];
22 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
23 println!(" Extending vector with data: {:?}", data);
24 x.extend(data);
25 });
26 let conditional = mutator.when(|x: &Vec<i32>| {
27 println!(" Checking condition: !x.is_empty()");
28 !x.is_empty()
29 });
30
31 let mut target = vec![0];
32 println!(" Initial: {:?}", target);
33 conditional.mutate_once(&mut target);
34 println!(" Result: {:?}\n", target);
35
36 // 2. Conditional execution - when condition is not satisfied
37 println!("2. Conditional execution - when condition is not satisfied");
38 let data = vec![4, 5, 6];
39 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
40 println!(" This should not be executed");
41 x.extend(data);
42 });
43 let conditional = mutator.when(|x: &Vec<i32>| {
44 println!(" Checking condition: x.len() > 10");
45 x.len() > 10
46 });
47
48 let mut target = vec![0];
49 println!(" Initial: {:?}", target);
50 conditional.mutate_once(&mut target);
51 println!(" Result: {:?} (unchanged)\n", target);
52
53 // 3. Using BoxPredicate
54 println!("3. Using BoxPredicate");
55 let pred = BoxPredicate::new(|x: &Vec<i32>| {
56 println!(" Predicate: checking if vector is not empty");
57 !x.is_empty()
58 });
59 let data = vec![7, 8, 9];
60 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
61 println!(" Adding data: {:?}", data);
62 x.extend(data);
63 });
64 let conditional = mutator.when(pred);
65
66 let mut target = vec![0];
67 println!(" Initial: {:?}", target);
68 conditional.mutate_once(&mut target);
69 println!(" Result: {:?}\n", target);
70
71 // 4. Using composed predicate
72 println!("4. Using composed predicate");
73 let pred = (|x: &Vec<i32>| {
74 println!(" Condition 1: !x.is_empty()");
75 !x.is_empty()
76 })
77 .and(|x: &Vec<i32>| {
78 println!(" Condition 2: x.len() < 10");
79 x.len() < 10
80 });
81 let data = vec![10, 11, 12];
82 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
83 println!(" Adding data: {:?}", data);
84 x.extend(data);
85 });
86 let conditional = mutator.when(pred);
87
88 let mut target = vec![0];
89 println!(" Initial: {:?}", target);
90 conditional.mutate_once(&mut target);
91 println!(" Result: {:?}\n", target);
92
93 // 5. If-then-else with or_else - when branch
94 println!("5. If-then-else with or_else - when branch");
95 let data1 = vec![1, 2, 3];
96 let data2 = vec![99];
97 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
98 println!(" When branch: adding {:?}", data1);
99 x.extend(data1);
100 })
101 .when(|x: &Vec<i32>| {
102 println!(" Checking: !x.is_empty()");
103 !x.is_empty()
104 })
105 .or_else(move |x: &mut Vec<i32>| {
106 println!(" Else branch: adding {:?}", data2);
107 x.extend(data2);
108 });
109
110 let mut target = vec![0];
111 println!(" Initial: {:?}", target);
112 mutator.mutate_once(&mut target);
113 println!(" Result: {:?}\n", target);
114
115 // 6. If-then-else with or_else - else branch
116 println!("6. If-then-else with or_else - else branch");
117 let data1 = vec![4, 5, 6];
118 let data2 = vec![99];
119 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
120 println!(" When branch: adding {:?}", data1);
121 x.extend(data1);
122 })
123 .when(|x: &Vec<i32>| {
124 println!(" Checking: x.is_empty()");
125 x.is_empty()
126 })
127 .or_else(move |x: &mut Vec<i32>| {
128 println!(" Else branch: adding {:?}", data2);
129 x.extend(data2);
130 });
131
132 let mut target = vec![0];
133 println!(" Initial: {:?}", target);
134 mutator.mutate_once(&mut target);
135 println!(" Result: {:?}\n", target);
136
137 // 7. Conditional with integers
138 println!("7. Conditional with integers");
139 let mutator = BoxMutatorOnce::new(|x: &mut i32| {
140 println!(" Multiplying by 2");
141 *x *= 2;
142 })
143 .when(|x: &i32| {
144 println!(" Checking: *x > 0");
145 *x > 0
146 });
147
148 let mut positive = 5;
149 println!(" Initial (positive): {}", positive);
150 mutator.mutate_once(&mut positive);
151 println!(" Result: {}\n", positive);
152
153 // 8. Conditional with integers - not executed
154 println!("8. Conditional with integers - not executed");
155 let mutator = BoxMutatorOnce::new(|x: &mut i32| {
156 println!(" This should not be executed");
157 *x *= 2;
158 })
159 .when(|x: &i32| {
160 println!(" Checking: *x > 0");
161 *x > 0
162 });
163
164 let mut negative = -5;
165 println!(" Initial (negative): {}", negative);
166 mutator.mutate_once(&mut negative);
167 println!(" Result: {} (unchanged)\n", negative);
168
169 // 9. Chaining conditional mutators
170 println!("9. Chaining conditional mutators");
171 let data1 = vec![1, 2];
172 let cond1 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
173 println!(" First mutator: adding {:?}", data1);
174 x.extend(data1);
175 })
176 .when(|x: &Vec<i32>| {
177 println!(" First condition: !x.is_empty()");
178 !x.is_empty()
179 });
180
181 let data2 = vec![3, 4];
182 let cond2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
183 println!(" Second mutator: adding {:?}", data2);
184 x.extend(data2);
185 })
186 .when(|x: &Vec<i32>| {
187 println!(" Second condition: x.len() < 10");
188 x.len() < 10
189 });
190
191 let chained = cond1.and_then(cond2);
192
193 let mut target = vec![0];
194 println!(" Initial: {:?}", target);
195 chained.mutate_once(&mut target);
196 println!(" Result: {:?}\n", target);
197
198 // 10. Complex conditional chain
199 println!("10. Complex conditional chain");
200 let data1 = vec![1, 2];
201 let data2 = vec![99];
202 let data3 = vec![5, 6];
203
204 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
205 println!(" When branch: adding {:?}", data1);
206 x.extend(data1);
207 })
208 .when(|x: &Vec<i32>| {
209 println!(" Checking: !x.is_empty()");
210 !x.is_empty()
211 })
212 .or_else(move |x: &mut Vec<i32>| {
213 println!(" Else branch: adding {:?}", data2);
214 x.extend(data2);
215 })
216 .and_then(move |x: &mut Vec<i32>| {
217 println!(" Final step: adding {:?}", data3);
218 x.extend(data3);
219 });
220
221 let mut target = vec![0];
222 println!(" Initial: {:?}", target);
223 mutator.mutate_once(&mut target);
224 println!(" Result: {:?}\n", target);
225
226 // 11. Real-world scenario: data validation and processing
227 println!("11. Real-world scenario: data validation and processing");
228
229 struct DataProcessor {
230 on_valid: Option<BoxMutatorOnce<Vec<String>>>,
231 on_invalid: Option<BoxMutatorOnce<Vec<String>>>,
232 }
233
234 impl DataProcessor {
235 fn new<V, I>(on_valid: V, on_invalid: I) -> Self
236 where
237 V: FnOnce(&mut Vec<String>) + 'static,
238 I: FnOnce(&mut Vec<String>) + 'static,
239 {
240 Self {
241 on_valid: Some(BoxMutatorOnce::new(on_valid)),
242 on_invalid: Some(BoxMutatorOnce::new(on_invalid)),
243 }
244 }
245
246 fn process(mut self, data: &mut Vec<String>) {
247 let is_valid = !data.is_empty() && data.iter().all(|s| !s.is_empty());
248 println!(
249 " Data validation: {}",
250 if is_valid { "VALID" } else { "INVALID" }
251 );
252
253 if is_valid {
254 if let Some(callback) = self.on_valid.take() {
255 callback.mutate_once(data);
256 }
257 } else if let Some(callback) = self.on_invalid.take() {
258 callback.mutate_once(data);
259 }
260 }
261 }
262
263 let valid_suffix = vec!["processed".to_string()];
264 let invalid_marker = vec!["[INVALID]".to_string()];
265
266 let processor = DataProcessor::new(
267 move |data| {
268 println!(" Valid data callback: adding suffix");
269 data.extend(valid_suffix);
270 },
271 move |data| {
272 println!(" Invalid data callback: adding error marker");
273 data.clear();
274 data.extend(invalid_marker);
275 },
276 );
277
278 let mut valid_data = vec!["item1".to_string(), "item2".to_string()];
279 println!(" Processing valid data: {:?}", valid_data);
280 processor.process(&mut valid_data);
281 println!(" Result: {:?}\n", valid_data);
282
283 println!("=== Examples completed ===");
284}Trait Implementations§
Source§impl<T> MutatorOnce<T> for BoxMutatorOnce<T>
impl<T> MutatorOnce<T> for BoxMutatorOnce<T>
Source§fn mutate_once(self, value: &mut T)
fn mutate_once(self, value: &mut T)
Source§fn into_box_once(self) -> BoxMutatorOnce<T>where
T: 'static,
fn into_box_once(self) -> BoxMutatorOnce<T>where
T: 'static,
BoxMutatorOnce (consuming) Read more