Skip to main content

mutator_once_demo/
mutator_once_demo.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 *    SPDX-License-Identifier: Apache-2.0
6 *
7 *    Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10//! # MutatorOnce Demo
11//!
12//! Demonstrates various usage scenarios of MutatorOnce
13
14use qubit_function::{
15    BoxMutatorOnce,
16    FnMutatorOnceOps,
17    MutatorOnce,
18};
19
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}