Skip to main content

FnMutatorOnceOps

Trait FnMutatorOnceOps 

Source
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§

Source

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. Since BoxMutatorOnce cannot be cloned, the parameter will be consumed. Can be:
    • A closure: |x: &mut T|
    • A BoxMutatorOnce<T>
    • Any type implementing MutatorOnce<T>
§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 usable
Examples 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§

Source§

impl<T, F> FnMutatorOnceOps<T> for F
where F: FnOnce(&mut T),

Implements FnMutatorOnceOps for all closure types