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