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 qubit_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.apply(&mut target);
assert_eq!(target, vec![0, 1, 2, 3]);§Method Chaining
use qubit_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.apply(&mut target);
assert_eq!(target, vec![0, 1, 2, 3, 4]);§Author
Haixing Hu
Implementations§
Source§impl<T> BoxMutatorOnce<T>
impl<T> BoxMutatorOnce<T>
Sourcepub fn new<F>(f: F) -> Self
pub fn new<F>(f: F) -> Self
Creates a new mutator.
Wraps the provided closure in the appropriate smart pointer type for this mutator implementation.
Examples found in repository?
19fn main() {
20 println!("=== MutatorOnce Examples ===\n");
21
22 // 1. Basic usage: moving captured variables
23 println!("1. Basic usage: moving captured variables");
24 let data = vec![1, 2, 3];
25 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
26 println!(" Adding data: {:?}", data);
27 x.extend(data);
28 });
29
30 let mut target = vec![0];
31 mutator.apply(&mut target);
32 println!(" Result: {:?}\n", target);
33
34 // 2. Method chaining: combining multiple operations
35 println!("2. Method chaining: combining multiple operations");
36 let prefix = vec![1, 2];
37 let middle = vec![3, 4];
38 let suffix = vec![5, 6];
39
40 let chained = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
41 println!(" Adding prefix: {:?}", prefix);
42 x.extend(prefix);
43 })
44 .and_then(move |x: &mut Vec<i32>| {
45 println!(" Adding middle: {:?}", middle);
46 x.extend(middle);
47 })
48 .and_then(move |x: &mut Vec<i32>| {
49 println!(" Adding suffix: {:?}", suffix);
50 x.extend(suffix);
51 });
52
53 let mut result = vec![0];
54 chained.apply(&mut result);
55 println!(" Result: {:?}\n", result);
56
57 // 3. Initializer pattern
58 println!("3. Initializer pattern");
59
60 struct Initializer {
61 name: String,
62 on_complete: Option<BoxMutatorOnce<Vec<String>>>,
63 }
64
65 impl Initializer {
66 fn new<F>(name: impl Into<String>, callback: F) -> Self
67 where
68 F: FnOnce(&mut Vec<String>) + 'static,
69 {
70 Self {
71 name: name.into(),
72 on_complete: Some(BoxMutatorOnce::new(callback)),
73 }
74 }
75
76 fn run(mut self, data: &mut Vec<String>) {
77 println!(" Initializer '{}' is running", self.name);
78 data.push(format!("Initialized by {}", self.name));
79
80 if let Some(callback) = self.on_complete.take() {
81 println!(" Executing completion callback");
82 callback.apply(data);
83 }
84 }
85 }
86
87 let extra = vec!["extra1".to_string(), "extra2".to_string()];
88 let init = Initializer::new("MainInit", move |values| {
89 println!(" Adding extra data in callback: {:?}", extra);
90 values.extend(extra);
91 });
92
93 let mut config = Vec::new();
94 init.run(&mut config);
95 println!(" Final config: {:?}\n", config);
96
97 // 4. String builder pattern
98 println!("4. String builder pattern");
99 let greeting = String::from("Hello, ");
100 let name = String::from("Alice");
101 let punctuation = String::from("!");
102
103 let builder = BoxMutatorOnce::new(move |s: &mut String| {
104 println!(" Adding greeting: {}", greeting);
105 s.insert_str(0, &greeting);
106 })
107 .and_then(move |s: &mut String| {
108 println!(" Adding name: {}", name);
109 s.push_str(&name);
110 })
111 .and_then(move |s: &mut String| {
112 println!(" Adding punctuation: {}", punctuation);
113 s.push_str(&punctuation);
114 })
115 .and_then(|s: &mut String| {
116 println!(" Converting to uppercase");
117 *s = s.to_uppercase();
118 });
119
120 let mut message = String::new();
121 builder.apply(&mut message);
122 println!(" Final message: {}\n", message);
123
124 // 5. Direct closure usage
125 println!("5. Direct closure usage");
126 let data1 = vec![10, 20];
127 let data2 = vec![30, 40];
128
129 let chained_closure = (move |x: &mut Vec<i32>| {
130 println!(" Step 1: Adding {:?}", data1);
131 x.extend(data1);
132 })
133 .and_then(move |x: &mut Vec<i32>| {
134 println!(" Step 2: Adding {:?}", data2);
135 x.extend(data2);
136 })
137 .and_then(|x: &mut Vec<i32>| {
138 println!(" Step 3: Multiplying each element by 2");
139 x.iter_mut().for_each(|n| *n *= 2);
140 });
141
142 let mut values = vec![0];
143 chained_closure.apply(&mut values);
144 println!(" Result: {:?}\n", values);
145
146 // 6. Resource transfer scenario
147 println!("6. Resource transfer scenario");
148 let large_data = vec![1; 10];
149 println!(
150 " Preparing to transfer large data (length: {})",
151 large_data.len()
152 );
153
154 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
155 println!(" Transferring data (moving, not cloning)");
156 x.extend(large_data); // large_data is moved, not cloned
157 });
158
159 let mut container = Vec::new();
160 mutator.apply(&mut container);
161 println!(" Data length in container: {}\n", container.len());
162
163 // 7. Generic function usage
164 println!("7. Generic function usage");
165
166 fn apply_transformation<M: MutatorOnce<Vec<i32>>>(mutator: M, initial: Vec<i32>) -> Vec<i32> {
167 let mut val = initial;
168 mutator.apply(&mut val);
169 val
170 }
171
172 let data = vec![100, 200, 300];
173 let result = apply_transformation(
174 move |x: &mut Vec<i32>| {
175 println!(" Adding in generic function: {:?}", data);
176 x.extend(data);
177 },
178 vec![0],
179 );
180 println!(" Result: {:?}\n", result);
181
182 // 8. Configuration builder
183 println!("8. Configuration builder");
184
185 struct Config {
186 options: Vec<String>,
187 }
188
189 impl Config {
190 fn new() -> Self {
191 Self {
192 options: Vec::new(),
193 }
194 }
195
196 fn with_defaults(mut self) -> Self {
197 println!(" Adding default options");
198 self.options.push("default1".to_string());
199 self.options.push("default2".to_string());
200 self
201 }
202
203 fn customize<F>(mut self, customizer: F) -> Self
204 where
205 F: FnOnce(&mut Vec<String>) + 'static,
206 {
207 println!(" Applying custom configuration");
208 customizer.apply(&mut self.options);
209 self
210 }
211
212 fn build(self) -> Self {
213 println!(" Configuration build completed");
214 self
215 }
216 }
217
218 let custom_opts = vec!["custom1".to_string(), "custom2".to_string()];
219 let config = Config::new()
220 .with_defaults()
221 .customize(move |opts| {
222 println!(" Adding custom options: {:?}", custom_opts);
223 opts.extend(custom_opts);
224 })
225 .build();
226
227 println!(" Final options: {:?}\n", config.options);
228
229 println!("=== Examples completed ===");
230}More examples
20fn main() {
21 println!("=== MutatorOnce Conditional Execution Examples ===\n");
22
23 // 1. Basic conditional execution - when condition is satisfied
24 println!("1. Basic conditional execution - when condition is satisfied");
25 let data = vec![1, 2, 3];
26 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
27 println!(" Extending vector with data: {:?}", data);
28 x.extend(data);
29 });
30 let conditional = mutator.when(|x: &Vec<i32>| {
31 println!(" Checking condition: !x.is_empty()");
32 !x.is_empty()
33 });
34
35 let mut target = vec![0];
36 println!(" Initial: {:?}", target);
37 conditional.apply(&mut target);
38 println!(" Result: {:?}\n", target);
39
40 // 2. Conditional execution - when condition is not satisfied
41 println!("2. Conditional execution - when condition is not satisfied");
42 let data = vec![4, 5, 6];
43 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
44 println!(" This should not be executed");
45 x.extend(data);
46 });
47 let conditional = mutator.when(|x: &Vec<i32>| {
48 println!(" Checking condition: x.len() > 10");
49 x.len() > 10
50 });
51
52 let mut target = vec![0];
53 println!(" Initial: {:?}", target);
54 conditional.apply(&mut target);
55 println!(" Result: {:?} (unchanged)\n", target);
56
57 // 3. Using BoxPredicate
58 println!("3. Using BoxPredicate");
59 let pred = BoxPredicate::new(|x: &Vec<i32>| {
60 println!(" Predicate: checking if vector is not empty");
61 !x.is_empty()
62 });
63 let data = vec![7, 8, 9];
64 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
65 println!(" Adding data: {:?}", data);
66 x.extend(data);
67 });
68 let conditional = mutator.when(pred);
69
70 let mut target = vec![0];
71 println!(" Initial: {:?}", target);
72 conditional.apply(&mut target);
73 println!(" Result: {:?}\n", target);
74
75 // 4. Using composed predicate
76 println!("4. Using composed predicate");
77 let pred = (|x: &Vec<i32>| {
78 println!(" Condition 1: !x.is_empty()");
79 !x.is_empty()
80 })
81 .and(|x: &Vec<i32>| {
82 println!(" Condition 2: x.len() < 10");
83 x.len() < 10
84 });
85 let data = vec![10, 11, 12];
86 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
87 println!(" Adding data: {:?}", data);
88 x.extend(data);
89 });
90 let conditional = mutator.when(pred);
91
92 let mut target = vec![0];
93 println!(" Initial: {:?}", target);
94 conditional.apply(&mut target);
95 println!(" Result: {:?}\n", target);
96
97 // 5. If-then-else with or_else - when branch
98 println!("5. If-then-else with or_else - when branch");
99 let data1 = vec![1, 2, 3];
100 let data2 = vec![99];
101 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
102 println!(" When branch: adding {:?}", data1);
103 x.extend(data1);
104 })
105 .when(|x: &Vec<i32>| {
106 println!(" Checking: !x.is_empty()");
107 !x.is_empty()
108 })
109 .or_else(move |x: &mut Vec<i32>| {
110 println!(" Else branch: adding {:?}", data2);
111 x.extend(data2);
112 });
113
114 let mut target = vec![0];
115 println!(" Initial: {:?}", target);
116 mutator.apply(&mut target);
117 println!(" Result: {:?}\n", target);
118
119 // 6. If-then-else with or_else - else branch
120 println!("6. If-then-else with or_else - else branch");
121 let data1 = vec![4, 5, 6];
122 let data2 = vec![99];
123 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
124 println!(" When branch: adding {:?}", data1);
125 x.extend(data1);
126 })
127 .when(|x: &Vec<i32>| {
128 println!(" Checking: x.is_empty()");
129 x.is_empty()
130 })
131 .or_else(move |x: &mut Vec<i32>| {
132 println!(" Else branch: adding {:?}", data2);
133 x.extend(data2);
134 });
135
136 let mut target = vec![0];
137 println!(" Initial: {:?}", target);
138 mutator.apply(&mut target);
139 println!(" Result: {:?}\n", target);
140
141 // 7. Conditional with integers
142 println!("7. Conditional with integers");
143 let mutator = BoxMutatorOnce::new(|x: &mut i32| {
144 println!(" Multiplying by 2");
145 *x *= 2;
146 })
147 .when(|x: &i32| {
148 println!(" Checking: *x > 0");
149 *x > 0
150 });
151
152 let mut positive = 5;
153 println!(" Initial (positive): {}", positive);
154 mutator.apply(&mut positive);
155 println!(" Result: {}\n", positive);
156
157 // 8. Conditional with integers - not executed
158 println!("8. Conditional with integers - not executed");
159 let mutator = BoxMutatorOnce::new(|x: &mut i32| {
160 println!(" This should not be executed");
161 *x *= 2;
162 })
163 .when(|x: &i32| {
164 println!(" Checking: *x > 0");
165 *x > 0
166 });
167
168 let mut negative = -5;
169 println!(" Initial (negative): {}", negative);
170 mutator.apply(&mut negative);
171 println!(" Result: {} (unchanged)\n", negative);
172
173 // 9. Chaining conditional mutators
174 println!("9. Chaining conditional mutators");
175 let data1 = vec![1, 2];
176 let cond1 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
177 println!(" First mutator: adding {:?}", data1);
178 x.extend(data1);
179 })
180 .when(|x: &Vec<i32>| {
181 println!(" First condition: !x.is_empty()");
182 !x.is_empty()
183 });
184
185 let data2 = vec![3, 4];
186 let cond2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
187 println!(" Second mutator: adding {:?}", data2);
188 x.extend(data2);
189 })
190 .when(|x: &Vec<i32>| {
191 println!(" Second condition: x.len() < 10");
192 x.len() < 10
193 });
194
195 let chained = cond1.and_then(cond2);
196
197 let mut target = vec![0];
198 println!(" Initial: {:?}", target);
199 chained.apply(&mut target);
200 println!(" Result: {:?}\n", target);
201
202 // 10. Complex conditional chain
203 println!("10. Complex conditional chain");
204 let data1 = vec![1, 2];
205 let data2 = vec![99];
206 let data3 = vec![5, 6];
207
208 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
209 println!(" When branch: adding {:?}", data1);
210 x.extend(data1);
211 })
212 .when(|x: &Vec<i32>| {
213 println!(" Checking: !x.is_empty()");
214 !x.is_empty()
215 })
216 .or_else(move |x: &mut Vec<i32>| {
217 println!(" Else branch: adding {:?}", data2);
218 x.extend(data2);
219 })
220 .and_then(move |x: &mut Vec<i32>| {
221 println!(" Final step: adding {:?}", data3);
222 x.extend(data3);
223 });
224
225 let mut target = vec![0];
226 println!(" Initial: {:?}", target);
227 mutator.apply(&mut target);
228 println!(" Result: {:?}\n", target);
229
230 // 11. Real-world scenario: data validation and processing
231 println!("11. Real-world scenario: data validation and processing");
232
233 struct DataProcessor {
234 on_valid: Option<BoxMutatorOnce<Vec<String>>>,
235 on_invalid: Option<BoxMutatorOnce<Vec<String>>>,
236 }
237
238 impl DataProcessor {
239 fn new<V, I>(on_valid: V, on_invalid: I) -> Self
240 where
241 V: FnOnce(&mut Vec<String>) + 'static,
242 I: FnOnce(&mut Vec<String>) + 'static,
243 {
244 Self {
245 on_valid: Some(BoxMutatorOnce::new(on_valid)),
246 on_invalid: Some(BoxMutatorOnce::new(on_invalid)),
247 }
248 }
249
250 fn process(mut self, data: &mut Vec<String>) {
251 let is_valid = !data.is_empty() && data.iter().all(|s| !s.is_empty());
252 println!(
253 " Data validation: {}",
254 if is_valid { "VALID" } else { "INVALID" }
255 );
256
257 if is_valid {
258 if let Some(callback) = self.on_valid.take() {
259 callback.apply(data);
260 }
261 } else if let Some(callback) = self.on_invalid.take() {
262 callback.apply(data);
263 }
264 }
265 }
266
267 let valid_suffix = vec!["processed".to_string()];
268 let invalid_marker = vec!["[INVALID]".to_string()];
269
270 let processor = DataProcessor::new(
271 move |data| {
272 println!(" Valid data callback: adding suffix");
273 data.extend(valid_suffix);
274 },
275 move |data| {
276 println!(" Invalid data callback: adding error marker");
277 data.clear();
278 data.extend(invalid_marker);
279 },
280 );
281
282 let mut valid_data = vec!["item1".to_string(), "item2".to_string()];
283 println!(" Processing valid data: {:?}", valid_data);
284 processor.process(&mut valid_data);
285 println!(" Result: {:?}\n", valid_data);
286
287 println!("=== Examples completed ===");
288}Sourcepub fn new_with_name<F>(name: &str, f: F) -> Self
pub fn new_with_name<F>(name: &str, f: F) -> Self
Creates a new named mutator.
Wraps the provided closure and assigns it a name, which is useful for debugging and logging purposes.
Sourcepub fn new_with_optional_name<F>(f: F, name: Option<String>) -> Self
pub fn new_with_optional_name<F>(f: F, name: Option<String>) -> Self
Creates a new named mutator with an optional name.
Wraps the provided closure and assigns it an optional name.
Sourcepub fn clear_name(&mut self)
pub fn clear_name(&mut self)
Clears the name of this mutator.
Sourcepub fn noop() -> Self
pub fn noop() -> Self
Creates a no-operation mutator.
Creates a mutator that does nothing when called. Useful for default values or placeholder implementations.
§Returns
Returns a new mutator instance that performs no operation.
Sourcepub fn when<P>(self, predicate: P) -> BoxConditionalMutatorOnce<T>where
T: 'static,
P: Predicate<T> + 'static,
pub fn when<P>(self, predicate: P) -> BoxConditionalMutatorOnce<T>where
T: 'static,
P: Predicate<T> + 'static,
Creates a conditional mutator that executes based on predicate result.
§Parameters
predicate- The predicate to determine whether to execute the mutation operation
§Returns
Returns a conditional mutator that only executes when the
predicate returns true.
§Examples
use std::sync::Arc;
use std::sync::atomic::{AtomicI32, Ordering};
use qubit_function::mutators::*;
let counter = Arc::new(AtomicI32::new(0));
let mutator = BoxMutator::new({
let counter = Arc::clone(&counter);
move |value: &mut i32| {
*value += counter.fetch_add(1, Ordering::SeqCst);
}
});
let conditional = mutator.when(|value: &i32| *value > 0);
let mut val = 1;
conditional.apply(&mut val); // val = 2 (1 + 1)
let mut val2 = -1;
conditional.apply(&mut val2); // not executed, val2 remains -1Examples found in repository?
20fn main() {
21 println!("=== MutatorOnce Conditional Execution Examples ===\n");
22
23 // 1. Basic conditional execution - when condition is satisfied
24 println!("1. Basic conditional execution - when condition is satisfied");
25 let data = vec![1, 2, 3];
26 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
27 println!(" Extending vector with data: {:?}", data);
28 x.extend(data);
29 });
30 let conditional = mutator.when(|x: &Vec<i32>| {
31 println!(" Checking condition: !x.is_empty()");
32 !x.is_empty()
33 });
34
35 let mut target = vec![0];
36 println!(" Initial: {:?}", target);
37 conditional.apply(&mut target);
38 println!(" Result: {:?}\n", target);
39
40 // 2. Conditional execution - when condition is not satisfied
41 println!("2. Conditional execution - when condition is not satisfied");
42 let data = vec![4, 5, 6];
43 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
44 println!(" This should not be executed");
45 x.extend(data);
46 });
47 let conditional = mutator.when(|x: &Vec<i32>| {
48 println!(" Checking condition: x.len() > 10");
49 x.len() > 10
50 });
51
52 let mut target = vec![0];
53 println!(" Initial: {:?}", target);
54 conditional.apply(&mut target);
55 println!(" Result: {:?} (unchanged)\n", target);
56
57 // 3. Using BoxPredicate
58 println!("3. Using BoxPredicate");
59 let pred = BoxPredicate::new(|x: &Vec<i32>| {
60 println!(" Predicate: checking if vector is not empty");
61 !x.is_empty()
62 });
63 let data = vec![7, 8, 9];
64 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
65 println!(" Adding data: {:?}", data);
66 x.extend(data);
67 });
68 let conditional = mutator.when(pred);
69
70 let mut target = vec![0];
71 println!(" Initial: {:?}", target);
72 conditional.apply(&mut target);
73 println!(" Result: {:?}\n", target);
74
75 // 4. Using composed predicate
76 println!("4. Using composed predicate");
77 let pred = (|x: &Vec<i32>| {
78 println!(" Condition 1: !x.is_empty()");
79 !x.is_empty()
80 })
81 .and(|x: &Vec<i32>| {
82 println!(" Condition 2: x.len() < 10");
83 x.len() < 10
84 });
85 let data = vec![10, 11, 12];
86 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
87 println!(" Adding data: {:?}", data);
88 x.extend(data);
89 });
90 let conditional = mutator.when(pred);
91
92 let mut target = vec![0];
93 println!(" Initial: {:?}", target);
94 conditional.apply(&mut target);
95 println!(" Result: {:?}\n", target);
96
97 // 5. If-then-else with or_else - when branch
98 println!("5. If-then-else with or_else - when branch");
99 let data1 = vec![1, 2, 3];
100 let data2 = vec![99];
101 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
102 println!(" When branch: adding {:?}", data1);
103 x.extend(data1);
104 })
105 .when(|x: &Vec<i32>| {
106 println!(" Checking: !x.is_empty()");
107 !x.is_empty()
108 })
109 .or_else(move |x: &mut Vec<i32>| {
110 println!(" Else branch: adding {:?}", data2);
111 x.extend(data2);
112 });
113
114 let mut target = vec![0];
115 println!(" Initial: {:?}", target);
116 mutator.apply(&mut target);
117 println!(" Result: {:?}\n", target);
118
119 // 6. If-then-else with or_else - else branch
120 println!("6. If-then-else with or_else - else branch");
121 let data1 = vec![4, 5, 6];
122 let data2 = vec![99];
123 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
124 println!(" When branch: adding {:?}", data1);
125 x.extend(data1);
126 })
127 .when(|x: &Vec<i32>| {
128 println!(" Checking: x.is_empty()");
129 x.is_empty()
130 })
131 .or_else(move |x: &mut Vec<i32>| {
132 println!(" Else branch: adding {:?}", data2);
133 x.extend(data2);
134 });
135
136 let mut target = vec![0];
137 println!(" Initial: {:?}", target);
138 mutator.apply(&mut target);
139 println!(" Result: {:?}\n", target);
140
141 // 7. Conditional with integers
142 println!("7. Conditional with integers");
143 let mutator = BoxMutatorOnce::new(|x: &mut i32| {
144 println!(" Multiplying by 2");
145 *x *= 2;
146 })
147 .when(|x: &i32| {
148 println!(" Checking: *x > 0");
149 *x > 0
150 });
151
152 let mut positive = 5;
153 println!(" Initial (positive): {}", positive);
154 mutator.apply(&mut positive);
155 println!(" Result: {}\n", positive);
156
157 // 8. Conditional with integers - not executed
158 println!("8. Conditional with integers - not executed");
159 let mutator = BoxMutatorOnce::new(|x: &mut i32| {
160 println!(" This should not be executed");
161 *x *= 2;
162 })
163 .when(|x: &i32| {
164 println!(" Checking: *x > 0");
165 *x > 0
166 });
167
168 let mut negative = -5;
169 println!(" Initial (negative): {}", negative);
170 mutator.apply(&mut negative);
171 println!(" Result: {} (unchanged)\n", negative);
172
173 // 9. Chaining conditional mutators
174 println!("9. Chaining conditional mutators");
175 let data1 = vec![1, 2];
176 let cond1 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
177 println!(" First mutator: adding {:?}", data1);
178 x.extend(data1);
179 })
180 .when(|x: &Vec<i32>| {
181 println!(" First condition: !x.is_empty()");
182 !x.is_empty()
183 });
184
185 let data2 = vec![3, 4];
186 let cond2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
187 println!(" Second mutator: adding {:?}", data2);
188 x.extend(data2);
189 })
190 .when(|x: &Vec<i32>| {
191 println!(" Second condition: x.len() < 10");
192 x.len() < 10
193 });
194
195 let chained = cond1.and_then(cond2);
196
197 let mut target = vec![0];
198 println!(" Initial: {:?}", target);
199 chained.apply(&mut target);
200 println!(" Result: {:?}\n", target);
201
202 // 10. Complex conditional chain
203 println!("10. Complex conditional chain");
204 let data1 = vec![1, 2];
205 let data2 = vec![99];
206 let data3 = vec![5, 6];
207
208 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
209 println!(" When branch: adding {:?}", data1);
210 x.extend(data1);
211 })
212 .when(|x: &Vec<i32>| {
213 println!(" Checking: !x.is_empty()");
214 !x.is_empty()
215 })
216 .or_else(move |x: &mut Vec<i32>| {
217 println!(" Else branch: adding {:?}", data2);
218 x.extend(data2);
219 })
220 .and_then(move |x: &mut Vec<i32>| {
221 println!(" Final step: adding {:?}", data3);
222 x.extend(data3);
223 });
224
225 let mut target = vec![0];
226 println!(" Initial: {:?}", target);
227 mutator.apply(&mut target);
228 println!(" Result: {:?}\n", target);
229
230 // 11. Real-world scenario: data validation and processing
231 println!("11. Real-world scenario: data validation and processing");
232
233 struct DataProcessor {
234 on_valid: Option<BoxMutatorOnce<Vec<String>>>,
235 on_invalid: Option<BoxMutatorOnce<Vec<String>>>,
236 }
237
238 impl DataProcessor {
239 fn new<V, I>(on_valid: V, on_invalid: I) -> Self
240 where
241 V: FnOnce(&mut Vec<String>) + 'static,
242 I: FnOnce(&mut Vec<String>) + 'static,
243 {
244 Self {
245 on_valid: Some(BoxMutatorOnce::new(on_valid)),
246 on_invalid: Some(BoxMutatorOnce::new(on_invalid)),
247 }
248 }
249
250 fn process(mut self, data: &mut Vec<String>) {
251 let is_valid = !data.is_empty() && data.iter().all(|s| !s.is_empty());
252 println!(
253 " Data validation: {}",
254 if is_valid { "VALID" } else { "INVALID" }
255 );
256
257 if is_valid {
258 if let Some(callback) = self.on_valid.take() {
259 callback.apply(data);
260 }
261 } else if let Some(callback) = self.on_invalid.take() {
262 callback.apply(data);
263 }
264 }
265 }
266
267 let valid_suffix = vec!["processed".to_string()];
268 let invalid_marker = vec!["[INVALID]".to_string()];
269
270 let processor = DataProcessor::new(
271 move |data| {
272 println!(" Valid data callback: adding suffix");
273 data.extend(valid_suffix);
274 },
275 move |data| {
276 println!(" Invalid data callback: adding error marker");
277 data.clear();
278 data.extend(invalid_marker);
279 },
280 );
281
282 let mut valid_data = vec!["item1".to_string(), "item2".to_string()];
283 println!(" Processing valid data: {:?}", valid_data);
284 processor.process(&mut valid_data);
285 println!(" Result: {:?}\n", valid_data);
286
287 println!("=== Examples completed ===");
288}Sourcepub fn and_then<M>(self, after: M) -> BoxMutatorOnce<T>where
Self: Sized + 'static,
T: 'static,
M: MutatorOnce<T> + 'static,
pub fn and_then<M>(self, after: M) -> BoxMutatorOnce<T>where
Self: Sized + 'static,
T: 'static,
M: MutatorOnce<T> + 'static,
Chains execution with another mutator, executing the current mutator first, then the subsequent mutator.
§Parameters
after- The subsequent mutator to execute after the current mutator completes
§Returns
Returns a new mutator that executes the current mutator and the subsequent mutator in sequence.
§Examples
use std::sync::Arc;
use std::sync::atomic::{AtomicI32, Ordering};
use qubit_function::mutators::*;
let counter1 = Arc::new(AtomicI32::new(0));
let counter2 = Arc::new(AtomicI32::new(0));
let mutator1 = BoxMutator::new({
let counter = Arc::clone(&counter1);
move |value: &mut i32| {
*value += counter.fetch_add(1, Ordering::SeqCst);
}
});
let mutator2 = BoxMutator::new({
let counter = Arc::clone(&counter2);
move |value: &mut i32| {
*value += counter.fetch_add(1, Ordering::SeqCst);
}
});
let chained = mutator1.and_then(mutator2);
let mut val = 0;
chained.apply(&mut val);
// val = 2 (0 + 1 + 1)Examples found in repository?
19fn main() {
20 println!("=== MutatorOnce Examples ===\n");
21
22 // 1. Basic usage: moving captured variables
23 println!("1. Basic usage: moving captured variables");
24 let data = vec![1, 2, 3];
25 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
26 println!(" Adding data: {:?}", data);
27 x.extend(data);
28 });
29
30 let mut target = vec![0];
31 mutator.apply(&mut target);
32 println!(" Result: {:?}\n", target);
33
34 // 2. Method chaining: combining multiple operations
35 println!("2. Method chaining: combining multiple operations");
36 let prefix = vec![1, 2];
37 let middle = vec![3, 4];
38 let suffix = vec![5, 6];
39
40 let chained = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
41 println!(" Adding prefix: {:?}", prefix);
42 x.extend(prefix);
43 })
44 .and_then(move |x: &mut Vec<i32>| {
45 println!(" Adding middle: {:?}", middle);
46 x.extend(middle);
47 })
48 .and_then(move |x: &mut Vec<i32>| {
49 println!(" Adding suffix: {:?}", suffix);
50 x.extend(suffix);
51 });
52
53 let mut result = vec![0];
54 chained.apply(&mut result);
55 println!(" Result: {:?}\n", result);
56
57 // 3. Initializer pattern
58 println!("3. Initializer pattern");
59
60 struct Initializer {
61 name: String,
62 on_complete: Option<BoxMutatorOnce<Vec<String>>>,
63 }
64
65 impl Initializer {
66 fn new<F>(name: impl Into<String>, callback: F) -> Self
67 where
68 F: FnOnce(&mut Vec<String>) + 'static,
69 {
70 Self {
71 name: name.into(),
72 on_complete: Some(BoxMutatorOnce::new(callback)),
73 }
74 }
75
76 fn run(mut self, data: &mut Vec<String>) {
77 println!(" Initializer '{}' is running", self.name);
78 data.push(format!("Initialized by {}", self.name));
79
80 if let Some(callback) = self.on_complete.take() {
81 println!(" Executing completion callback");
82 callback.apply(data);
83 }
84 }
85 }
86
87 let extra = vec!["extra1".to_string(), "extra2".to_string()];
88 let init = Initializer::new("MainInit", move |values| {
89 println!(" Adding extra data in callback: {:?}", extra);
90 values.extend(extra);
91 });
92
93 let mut config = Vec::new();
94 init.run(&mut config);
95 println!(" Final config: {:?}\n", config);
96
97 // 4. String builder pattern
98 println!("4. String builder pattern");
99 let greeting = String::from("Hello, ");
100 let name = String::from("Alice");
101 let punctuation = String::from("!");
102
103 let builder = BoxMutatorOnce::new(move |s: &mut String| {
104 println!(" Adding greeting: {}", greeting);
105 s.insert_str(0, &greeting);
106 })
107 .and_then(move |s: &mut String| {
108 println!(" Adding name: {}", name);
109 s.push_str(&name);
110 })
111 .and_then(move |s: &mut String| {
112 println!(" Adding punctuation: {}", punctuation);
113 s.push_str(&punctuation);
114 })
115 .and_then(|s: &mut String| {
116 println!(" Converting to uppercase");
117 *s = s.to_uppercase();
118 });
119
120 let mut message = String::new();
121 builder.apply(&mut message);
122 println!(" Final message: {}\n", message);
123
124 // 5. Direct closure usage
125 println!("5. Direct closure usage");
126 let data1 = vec![10, 20];
127 let data2 = vec![30, 40];
128
129 let chained_closure = (move |x: &mut Vec<i32>| {
130 println!(" Step 1: Adding {:?}", data1);
131 x.extend(data1);
132 })
133 .and_then(move |x: &mut Vec<i32>| {
134 println!(" Step 2: Adding {:?}", data2);
135 x.extend(data2);
136 })
137 .and_then(|x: &mut Vec<i32>| {
138 println!(" Step 3: Multiplying each element by 2");
139 x.iter_mut().for_each(|n| *n *= 2);
140 });
141
142 let mut values = vec![0];
143 chained_closure.apply(&mut values);
144 println!(" Result: {:?}\n", values);
145
146 // 6. Resource transfer scenario
147 println!("6. Resource transfer scenario");
148 let large_data = vec![1; 10];
149 println!(
150 " Preparing to transfer large data (length: {})",
151 large_data.len()
152 );
153
154 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
155 println!(" Transferring data (moving, not cloning)");
156 x.extend(large_data); // large_data is moved, not cloned
157 });
158
159 let mut container = Vec::new();
160 mutator.apply(&mut container);
161 println!(" Data length in container: {}\n", container.len());
162
163 // 7. Generic function usage
164 println!("7. Generic function usage");
165
166 fn apply_transformation<M: MutatorOnce<Vec<i32>>>(mutator: M, initial: Vec<i32>) -> Vec<i32> {
167 let mut val = initial;
168 mutator.apply(&mut val);
169 val
170 }
171
172 let data = vec![100, 200, 300];
173 let result = apply_transformation(
174 move |x: &mut Vec<i32>| {
175 println!(" Adding in generic function: {:?}", data);
176 x.extend(data);
177 },
178 vec![0],
179 );
180 println!(" Result: {:?}\n", result);
181
182 // 8. Configuration builder
183 println!("8. Configuration builder");
184
185 struct Config {
186 options: Vec<String>,
187 }
188
189 impl Config {
190 fn new() -> Self {
191 Self {
192 options: Vec::new(),
193 }
194 }
195
196 fn with_defaults(mut self) -> Self {
197 println!(" Adding default options");
198 self.options.push("default1".to_string());
199 self.options.push("default2".to_string());
200 self
201 }
202
203 fn customize<F>(mut self, customizer: F) -> Self
204 where
205 F: FnOnce(&mut Vec<String>) + 'static,
206 {
207 println!(" Applying custom configuration");
208 customizer.apply(&mut self.options);
209 self
210 }
211
212 fn build(self) -> Self {
213 println!(" Configuration build completed");
214 self
215 }
216 }
217
218 let custom_opts = vec!["custom1".to_string(), "custom2".to_string()];
219 let config = Config::new()
220 .with_defaults()
221 .customize(move |opts| {
222 println!(" Adding custom options: {:?}", custom_opts);
223 opts.extend(custom_opts);
224 })
225 .build();
226
227 println!(" Final options: {:?}\n", config.options);
228
229 println!("=== Examples completed ===");
230}More examples
20fn main() {
21 println!("=== MutatorOnce Conditional Execution Examples ===\n");
22
23 // 1. Basic conditional execution - when condition is satisfied
24 println!("1. Basic conditional execution - when condition is satisfied");
25 let data = vec![1, 2, 3];
26 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
27 println!(" Extending vector with data: {:?}", data);
28 x.extend(data);
29 });
30 let conditional = mutator.when(|x: &Vec<i32>| {
31 println!(" Checking condition: !x.is_empty()");
32 !x.is_empty()
33 });
34
35 let mut target = vec![0];
36 println!(" Initial: {:?}", target);
37 conditional.apply(&mut target);
38 println!(" Result: {:?}\n", target);
39
40 // 2. Conditional execution - when condition is not satisfied
41 println!("2. Conditional execution - when condition is not satisfied");
42 let data = vec![4, 5, 6];
43 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
44 println!(" This should not be executed");
45 x.extend(data);
46 });
47 let conditional = mutator.when(|x: &Vec<i32>| {
48 println!(" Checking condition: x.len() > 10");
49 x.len() > 10
50 });
51
52 let mut target = vec![0];
53 println!(" Initial: {:?}", target);
54 conditional.apply(&mut target);
55 println!(" Result: {:?} (unchanged)\n", target);
56
57 // 3. Using BoxPredicate
58 println!("3. Using BoxPredicate");
59 let pred = BoxPredicate::new(|x: &Vec<i32>| {
60 println!(" Predicate: checking if vector is not empty");
61 !x.is_empty()
62 });
63 let data = vec![7, 8, 9];
64 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
65 println!(" Adding data: {:?}", data);
66 x.extend(data);
67 });
68 let conditional = mutator.when(pred);
69
70 let mut target = vec![0];
71 println!(" Initial: {:?}", target);
72 conditional.apply(&mut target);
73 println!(" Result: {:?}\n", target);
74
75 // 4. Using composed predicate
76 println!("4. Using composed predicate");
77 let pred = (|x: &Vec<i32>| {
78 println!(" Condition 1: !x.is_empty()");
79 !x.is_empty()
80 })
81 .and(|x: &Vec<i32>| {
82 println!(" Condition 2: x.len() < 10");
83 x.len() < 10
84 });
85 let data = vec![10, 11, 12];
86 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
87 println!(" Adding data: {:?}", data);
88 x.extend(data);
89 });
90 let conditional = mutator.when(pred);
91
92 let mut target = vec![0];
93 println!(" Initial: {:?}", target);
94 conditional.apply(&mut target);
95 println!(" Result: {:?}\n", target);
96
97 // 5. If-then-else with or_else - when branch
98 println!("5. If-then-else with or_else - when branch");
99 let data1 = vec![1, 2, 3];
100 let data2 = vec![99];
101 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
102 println!(" When branch: adding {:?}", data1);
103 x.extend(data1);
104 })
105 .when(|x: &Vec<i32>| {
106 println!(" Checking: !x.is_empty()");
107 !x.is_empty()
108 })
109 .or_else(move |x: &mut Vec<i32>| {
110 println!(" Else branch: adding {:?}", data2);
111 x.extend(data2);
112 });
113
114 let mut target = vec![0];
115 println!(" Initial: {:?}", target);
116 mutator.apply(&mut target);
117 println!(" Result: {:?}\n", target);
118
119 // 6. If-then-else with or_else - else branch
120 println!("6. If-then-else with or_else - else branch");
121 let data1 = vec![4, 5, 6];
122 let data2 = vec![99];
123 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
124 println!(" When branch: adding {:?}", data1);
125 x.extend(data1);
126 })
127 .when(|x: &Vec<i32>| {
128 println!(" Checking: x.is_empty()");
129 x.is_empty()
130 })
131 .or_else(move |x: &mut Vec<i32>| {
132 println!(" Else branch: adding {:?}", data2);
133 x.extend(data2);
134 });
135
136 let mut target = vec![0];
137 println!(" Initial: {:?}", target);
138 mutator.apply(&mut target);
139 println!(" Result: {:?}\n", target);
140
141 // 7. Conditional with integers
142 println!("7. Conditional with integers");
143 let mutator = BoxMutatorOnce::new(|x: &mut i32| {
144 println!(" Multiplying by 2");
145 *x *= 2;
146 })
147 .when(|x: &i32| {
148 println!(" Checking: *x > 0");
149 *x > 0
150 });
151
152 let mut positive = 5;
153 println!(" Initial (positive): {}", positive);
154 mutator.apply(&mut positive);
155 println!(" Result: {}\n", positive);
156
157 // 8. Conditional with integers - not executed
158 println!("8. Conditional with integers - not executed");
159 let mutator = BoxMutatorOnce::new(|x: &mut i32| {
160 println!(" This should not be executed");
161 *x *= 2;
162 })
163 .when(|x: &i32| {
164 println!(" Checking: *x > 0");
165 *x > 0
166 });
167
168 let mut negative = -5;
169 println!(" Initial (negative): {}", negative);
170 mutator.apply(&mut negative);
171 println!(" Result: {} (unchanged)\n", negative);
172
173 // 9. Chaining conditional mutators
174 println!("9. Chaining conditional mutators");
175 let data1 = vec![1, 2];
176 let cond1 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
177 println!(" First mutator: adding {:?}", data1);
178 x.extend(data1);
179 })
180 .when(|x: &Vec<i32>| {
181 println!(" First condition: !x.is_empty()");
182 !x.is_empty()
183 });
184
185 let data2 = vec![3, 4];
186 let cond2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
187 println!(" Second mutator: adding {:?}", data2);
188 x.extend(data2);
189 })
190 .when(|x: &Vec<i32>| {
191 println!(" Second condition: x.len() < 10");
192 x.len() < 10
193 });
194
195 let chained = cond1.and_then(cond2);
196
197 let mut target = vec![0];
198 println!(" Initial: {:?}", target);
199 chained.apply(&mut target);
200 println!(" Result: {:?}\n", target);
201
202 // 10. Complex conditional chain
203 println!("10. Complex conditional chain");
204 let data1 = vec![1, 2];
205 let data2 = vec![99];
206 let data3 = vec![5, 6];
207
208 let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
209 println!(" When branch: adding {:?}", data1);
210 x.extend(data1);
211 })
212 .when(|x: &Vec<i32>| {
213 println!(" Checking: !x.is_empty()");
214 !x.is_empty()
215 })
216 .or_else(move |x: &mut Vec<i32>| {
217 println!(" Else branch: adding {:?}", data2);
218 x.extend(data2);
219 })
220 .and_then(move |x: &mut Vec<i32>| {
221 println!(" Final step: adding {:?}", data3);
222 x.extend(data3);
223 });
224
225 let mut target = vec![0];
226 println!(" Initial: {:?}", target);
227 mutator.apply(&mut target);
228 println!(" Result: {:?}\n", target);
229
230 // 11. Real-world scenario: data validation and processing
231 println!("11. Real-world scenario: data validation and processing");
232
233 struct DataProcessor {
234 on_valid: Option<BoxMutatorOnce<Vec<String>>>,
235 on_invalid: Option<BoxMutatorOnce<Vec<String>>>,
236 }
237
238 impl DataProcessor {
239 fn new<V, I>(on_valid: V, on_invalid: I) -> Self
240 where
241 V: FnOnce(&mut Vec<String>) + 'static,
242 I: FnOnce(&mut Vec<String>) + 'static,
243 {
244 Self {
245 on_valid: Some(BoxMutatorOnce::new(on_valid)),
246 on_invalid: Some(BoxMutatorOnce::new(on_invalid)),
247 }
248 }
249
250 fn process(mut self, data: &mut Vec<String>) {
251 let is_valid = !data.is_empty() && data.iter().all(|s| !s.is_empty());
252 println!(
253 " Data validation: {}",
254 if is_valid { "VALID" } else { "INVALID" }
255 );
256
257 if is_valid {
258 if let Some(callback) = self.on_valid.take() {
259 callback.apply(data);
260 }
261 } else if let Some(callback) = self.on_invalid.take() {
262 callback.apply(data);
263 }
264 }
265 }
266
267 let valid_suffix = vec!["processed".to_string()];
268 let invalid_marker = vec!["[INVALID]".to_string()];
269
270 let processor = DataProcessor::new(
271 move |data| {
272 println!(" Valid data callback: adding suffix");
273 data.extend(valid_suffix);
274 },
275 move |data| {
276 println!(" Invalid data callback: adding error marker");
277 data.clear();
278 data.extend(invalid_marker);
279 },
280 );
281
282 let mut valid_data = vec!["item1".to_string(), "item2".to_string()];
283 println!(" Processing valid data: {:?}", valid_data);
284 processor.process(&mut valid_data);
285 println!(" Result: {:?}\n", valid_data);
286
287 println!("=== Examples completed ===");
288}