pub struct BoxConditionalMutatorOnce<T> { /* private fields */ }Expand description
BoxConditionalMutatorOnce struct
A conditional one-time mutator that only executes when a predicate is satisfied.
Uses BoxMutatorOnce and BoxPredicate for single ownership semantics.
This type is typically created by calling BoxMutatorOnce::when() and is
designed to work with the or_else() method to create if-then-else logic.
§Features
- Single Ownership: Not cloneable, consumes
selfon use - Conditional Execution: Only mutates when predicate returns
true - Chainable: Can add
or_elsebranch to create if-then-else logic - Implements MutatorOnce: Can be used anywhere a
MutatorOnceis expected
§Examples
§Basic Conditional Execution
use qubit_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.apply(&mut target);
assert_eq!(target, vec![0, 1, 2, 3]); // Executed
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.apply(&mut empty);
assert_eq!(empty, Vec::<i32>::new()); // Not executed§With or_else Branch
use qubit_function::{MutatorOnce, BoxMutatorOnce};
let data1 = vec![1, 2, 3];
let data2 = vec![99];
let mutator = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
x.extend(data1);
})
.when(|x: &Vec<i32>| !x.is_empty())
.or_else(move |x: &mut Vec<i32>| {
x.extend(data2);
});
let mut target = vec![0];
mutator.apply(&mut target);
assert_eq!(target, vec![0, 1, 2, 3]); // when branch executed
let data3 = vec![4, 5];
let data4 = vec![99];
let mutator2 = BoxMutatorOnce::new(move |x: &mut Vec<i32>| {
x.extend(data3);
})
.when(|x: &Vec<i32>| x.is_empty())
.or_else(move |x: &mut Vec<i32>| {
x.extend(data4);
});
let mut target2 = vec![0];
mutator2.apply(&mut target2);
assert_eq!(target2, vec![0, 99]); // or_else branch executed§Author
Haixing Hu
Implementations§
Source§impl<T> BoxConditionalMutatorOnce<T>
impl<T> BoxConditionalMutatorOnce<T>
Sourcepub fn and_then<M>(self, next: M) -> BoxMutatorOnce<T>where
T: 'static,
M: MutatorOnce<T> + 'static,
pub fn and_then<M>(self, next: M) -> BoxMutatorOnce<T>where
T: 'static,
M: MutatorOnce<T> + 'static,
Chains another mutator in sequence
Combines the current conditional mutator with another mutator into a new mutator that implements the following semantics:
When the returned mutator is called with an argument:
- First, it checks the predicate of this conditional mutator
- If the predicate is satisfied, it executes the internal mutator of this conditional mutator
- Then, regardless of whether the predicate was satisfied,
it unconditionally executes the
nextmutator
In other words, this creates a mutator that conditionally executes the first action (based on the predicate), and then always executes the second action.
§Parameters
next- The next mutator to execute (always executed)
§Returns
Returns a new combined mutator
§Examples
// use std::sync::atomic::{AtomicI32, Ordering};
//
// let result = AtomicI32::new(0);
//
// let mutator1 = BoxMutator::new(|x: &mut i32| {
// *x += 1;
// });
//
// let mutator2 = BoxMutator::new(|x: &mut i32| {
// *x += 2;
// });
//
// let conditional = mutator1.when(|x| *x > 0);
// let chained = conditional.and_then(mutator2);
//
// let mut val = 5;
// chained.apply(&mut val); // val = 5 + 1 + 2 = 8
// let mut val2 = -1;
// chained.apply(&mut val2); // val2 = -1 + 2 = 1 (not -1 + 1 + 2!)
// ```Examples 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 or_else<M>(self, else_mutator: M) -> BoxMutatorOnce<T>where
T: 'static,
M: MutatorOnce<T> + 'static,
pub fn or_else<M>(self, else_mutator: M) -> BoxMutatorOnce<T>where
T: 'static,
M: MutatorOnce<T> + 'static,
Adds an else branch
Executes the original mutator when the condition is satisfied, otherwise executes else_mutator.
§Parameters
else_mutator- The mutator for the else branch
§Returns
Returns a new mutator with if-then-else logic
Examples 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}