flag_completion_demo/
flag_completion_demo.rs1use flag_rs::{CommandBuilder, CompletionResult, Flag};
3
4fn main() {
5 let app = CommandBuilder::new("deploy")
6 .short("Deploy application to various environments")
7 .flag(
8 Flag::choice("environment", &["dev", "staging", "prod"])
9 .short('e')
10 .usage("Target environment")
11 .required()
12 .completion(|_ctx, prefix| {
13 let environments = vec![
15 ("dev", "Development environment"),
16 ("staging", "Staging environment (pre-production)"),
17 ("prod", "Production environment"),
18 ];
19
20 let mut result = CompletionResult::new();
21 for (env, desc) in environments {
22 if env.starts_with(prefix) {
23 result = result.add_with_description(env.to_string(), desc.to_string());
24 }
25 }
26
27 if prefix.is_empty() {
29 result = result.add_help_text("Available environments: dev, staging, prod");
30 }
31
32 Ok(result)
33 }),
34 )
35 .flag(
36 Flag::file("config")
37 .short('c')
38 .usage("Configuration file")
39 .default_str("config.yaml")
40 .completion(|_ctx, prefix| {
41 let configs = vec![
43 "config.yaml",
44 "config.dev.yaml",
45 "config.staging.yaml",
46 "config.prod.yaml",
47 "secrets.yaml",
48 ];
49
50 Ok(CompletionResult::new().extend(
51 configs
52 .into_iter()
53 .filter(|c| c.starts_with(prefix))
54 .map(String::from),
55 ))
56 }),
57 )
58 .flag(
59 Flag::directory("output")
60 .short('o')
61 .usage("Output directory for deployment artifacts")
62 .completion(|_ctx, prefix| {
63 let dirs = vec!["./build", "./dist", "./output", "/tmp/deploy"];
65
66 Ok(CompletionResult::new().extend(
67 dirs.into_iter()
68 .filter(|d| d.starts_with(prefix))
69 .map(String::from),
70 ))
71 }),
72 )
73 .flag(
74 Flag::string_slice("service")
75 .short('s')
76 .usage("Services to deploy (can be specified multiple times)")
77 .completion(|ctx, prefix| {
78 let env = ctx.flag_str_or("environment", "dev");
80
81 let services = match env {
82 "dev" => vec!["api", "web", "worker", "scheduler", "debug-panel"],
83 "staging" => vec!["api", "web", "worker", "scheduler"],
84 "prod" => vec!["api", "web", "worker"],
85 _ => vec!["api", "web"],
86 };
87
88 let mut result = CompletionResult::new().extend(
89 services
90 .into_iter()
91 .filter(|s| s.starts_with(prefix))
92 .map(String::from),
93 );
94
95 if prefix.is_empty() {
97 result = result
98 .add_help_text(format!("Available services for {} environment", env));
99 }
100
101 Ok(result)
102 }),
103 )
104 .flag(
105 Flag::range("replicas", 1, 10)
106 .short('r')
107 .usage("Number of replicas to deploy")
108 .default_int(2)
109 .completion(|_ctx, _prefix| {
110 Ok(CompletionResult::new()
112 .add_with_description(
113 "1".to_string(),
114 "Single instance (dev/test)".to_string(),
115 )
116 .add_with_description("2".to_string(), "Basic redundancy".to_string())
117 .add_with_description("3".to_string(), "Standard production".to_string())
118 .add_with_description("5".to_string(), "High availability".to_string()))
119 }),
120 )
121 .run(|ctx| {
122 let env = ctx.flag_str_or("environment", "dev");
123 let config = ctx.flag_str_or("config", "config.yaml");
124 let replicas = ctx.flag_int_or("replicas", 2);
125
126 println!("Deploying to {} environment", env);
127 println!("Using configuration: {}", config);
128 println!("Replica count: {}", replicas);
129
130 if let Some(output) = ctx.flag("output") {
131 println!("Output directory: {}", output);
132 }
133
134 if let Some(services) = ctx.flag("service") {
135 println!("Deploying services: {}", services);
136 } else {
137 println!("Deploying all services");
138 }
139
140 Ok(())
141 })
142 .build();
143
144 let args: Vec<String> = std::env::args().skip(1).collect();
145 if let Err(e) = app.execute(args) {
146 eprintln!("Error: {}", e);
147 std::process::exit(1);
148 }
149}