pub trait FnMutatorOnceOps<T>: FnOnce(&mut T) + Sized {
// Provided method
fn and_then<C>(self, next: C) -> BoxMutatorOnce<T>
where Self: 'static,
C: MutatorOnce<T> + 'static,
T: 'static { ... }
}Expand description
Extension trait providing one-time mutator composition methods for closures
Provides and_then and other composition methods for all closures that
implement FnOnce(&mut T), enabling direct method chaining on closures
without explicit wrapper types.
§Features
- Natural Syntax: Chain operations directly on closures
- Returns BoxMutatorOnce: Composition results are
BoxMutatorOnce<T>for continued chaining - Zero Cost: No overhead when composing closures
- Automatic Implementation: All
FnOnce(&mut T)closures get these methods automatically
§Examples
use qubit_function::{MutatorOnce, FnMutatorOnceOps};
let data1 = vec![1, 2];
let data2 = vec![3, 4];
let chained = (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
Provided Methods§
Sourcefn and_then<C>(self, next: C) -> BoxMutatorOnce<T>where
Self: 'static,
C: MutatorOnce<T> + 'static,
T: 'static,
fn and_then<C>(self, next: C) -> BoxMutatorOnce<T>where
Self: 'static,
C: MutatorOnce<T> + 'static,
T: 'static,
Chains another mutator in sequence
Returns a new mutator that first executes the current operation, then
executes the next operation. Consumes the current closure and returns
BoxMutatorOnce<T>.
§Parameters
next- The mutator to execute after the current operation. Note: This parameter is passed by value and will transfer ownership. SinceBoxMutatorOncecannot be cloned, the parameter will be consumed. Can be:- A closure:
|x: &mut T| - A
BoxMutatorOnce<T> - Any type implementing
MutatorOnce<T>
- A closure:
§Returns
Returns the composed BoxMutatorOnce<T>
§Examples
use qubit_function::{MutatorOnce, FnMutatorOnceOps};
let data1 = vec![1, 2];
let data2 = vec![3, 4];
// Both closures are moved and consumed
let chained = (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]);
// The original closures are consumed and no longer usableExamples found in repository?
examples/mutators/mutator_once_demo.rs (lines 133-136)
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}Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
Implementors§
impl<T, F> FnMutatorOnceOps<T> for F
Implements FnMutatorOnceOps for all closure types