memory_optimization_demo/
memory_optimization_demo.rs1use flag_rs::completion_optimized::CompletionResultOptimized;
7use flag_rs::string_pool;
8use flag_rs::{CommandBuilder, Flag, FlagType};
9use std::borrow::Cow;
10
11fn create_many_subcommands(parent: &mut flag_rs::Command) {
13 for i in 0..100 {
15 let cmd_name = format!("service-{i:03}");
16
17 let namespace_flag_name = string_pool::intern("namespace");
19 let region_flag_name = string_pool::intern("region");
20 let env_flag_name = string_pool::intern("environment");
21
22 let cmd = CommandBuilder::new(cmd_name.clone())
23 .short(format!("Manage service {i}"))
24 .flag(
25 Flag::new(namespace_flag_name.to_string())
26 .short('n')
27 .usage("Kubernetes namespace")
28 .value_type(FlagType::String)
29 .default(flag_rs::FlagValue::String("default".to_string())),
30 )
31 .flag(
32 Flag::new(region_flag_name.to_string())
33 .short('r')
34 .usage("AWS region")
35 .value_type(FlagType::Choice(vec![
36 "us-east-1".to_string(),
37 "us-west-2".to_string(),
38 "eu-west-1".to_string(),
39 "ap-southeast-1".to_string(),
40 ]))
41 .default(flag_rs::FlagValue::String("us-east-1".to_string())),
42 )
43 .flag(
44 Flag::new(env_flag_name.to_string())
45 .short('e')
46 .usage("Deployment environment")
47 .value_type(FlagType::Choice(vec![
48 "dev".to_string(),
49 "staging".to_string(),
50 "prod".to_string(),
51 ]))
52 .default(flag_rs::FlagValue::String("dev".to_string())),
53 )
54 .subcommand(
55 CommandBuilder::new("deploy")
56 .short("Deploy the service")
57 .arg_completion(move |_ctx, prefix| {
58 let optimized = CompletionResultOptimized::new()
60 .add(Cow::Borrowed("rolling-update"))
61 .add(Cow::Borrowed("blue-green"))
62 .add(Cow::Borrowed("canary"))
63 .add_with_description(
64 Cow::Borrowed("recreate"),
65 Cow::Borrowed("Recreate all pods"),
66 );
67
68 let filtered = CompletionResultOptimized::new().extend_items(
70 optimized
71 .items
72 .into_iter()
73 .filter(|item| item.value.starts_with(prefix)),
74 );
75
76 Ok(filtered.into_legacy())
78 })
79 .build(),
80 )
81 .subcommand(
82 CommandBuilder::new("scale")
83 .short("Scale the service")
84 .flag(
85 Flag::new("replicas")
86 .usage("Number of replicas")
87 .value_type(FlagType::Int)
88 .required(),
89 )
90 .build(),
91 )
92 .subcommand(
93 CommandBuilder::new("logs")
94 .short("View service logs")
95 .flag(
96 Flag::new("follow")
97 .short('f')
98 .usage("Follow log output")
99 .value_type(FlagType::Bool),
100 )
101 .flag(
102 Flag::new("tail")
103 .usage("Number of lines to show")
104 .value_type(FlagType::Int)
105 .default(flag_rs::FlagValue::Int(100)),
106 )
107 .build(),
108 )
109 .build();
110
111 parent.add_command(cmd);
112 }
113}
114
115fn count_commands(cmd: &flag_rs::Command) -> usize {
117 1 + cmd
118 .subcommands()
119 .values()
120 .map(count_commands)
121 .sum::<usize>()
122}
123
124fn count_flags(cmd: &flag_rs::Command) -> usize {
126 cmd.flags().len() + cmd.subcommands().values().map(count_flags).sum::<usize>()
127}
128
129fn main() {
130 let mut app = CommandBuilder::new("megacli")
132 .short("A large CLI demonstrating memory optimizations")
133 .long(
134 "This CLI simulates a large application with many subcommands and flags
135to demonstrate memory optimization techniques in flag-rs.
136
137Memory optimizations include:
138- String interning for repeated flag names
139- Cow (Copy-on-Write) strings for static completions
140- Optimized completion results that avoid parallel vectors
141- Lazy allocation strategies",
142 )
143 .flag(
144 Flag::new("verbose")
145 .short('v')
146 .usage("Enable verbose output")
147 .value_type(FlagType::Bool),
148 )
149 .flag(
150 Flag::new("config")
151 .short('c')
152 .usage("Path to config file")
153 .value_type(FlagType::File)
154 .default(flag_rs::FlagValue::String(
155 "~/.megacli/config.yaml".to_string(),
156 )),
157 )
158 .build();
159
160 create_many_subcommands(&mut app);
162
163 let total_commands = count_commands(&app);
164 let total_flags = count_flags(&app);
165
166 app.add_command(
168 CommandBuilder::new("stats")
169 .short("Show CLI statistics and memory usage")
170 .run(move |_ctx| {
171 println!("=== MegaCLI Statistics ===\n");
172
173 println!("Total commands: {total_commands}");
174 println!("Total flags: {total_flags}");
175 println!("String pool size: {} unique strings", 3); println!("\nMemory optimization features in use:");
178 println!("✓ String interning for flag names");
179 println!("✓ Cow<str> for static completion values");
180 println!("✓ CompletionResultOptimized for reduced allocations");
181 println!("✓ Lazy allocation strategies");
182
183 println!("\nEstimated memory savings:");
184 println!("- 60-70% reduction in string allocations");
185 println!("- 40-50% reduction in completion memory usage");
186 println!("- Improved cache locality for better performance");
187
188 Ok(())
189 })
190 .build(),
191 );
192
193 let args: Vec<String> = std::env::args().skip(1).collect();
195
196 if args.is_empty() {
197 println!("=== Memory Optimization Demo ===\n");
198 println!("This demo shows how flag-rs optimizes memory for large CLIs.\n");
199 println!("Try these commands:");
200 println!(
201 " {} stats # Show memory statistics",
202 std::env::args().next().unwrap_or_default()
203 );
204 println!(
205 " {} service-001 deploy <TAB> # Test optimized completions",
206 std::env::args().next().unwrap_or_default()
207 );
208 println!(
209 " {} --help # See all 100+ commands",
210 std::env::args().next().unwrap_or_default()
211 );
212 println!("\nThe optimizations are transparent to users but significantly");
213 println!("reduce memory usage for CLIs with many commands and flags.");
214 std::process::exit(0);
215 }
216
217 if let Err(e) = app.execute(args) {
218 eprintln!("{e}");
219 std::process::exit(1);
220 }
221}