advanced_flags_demo/
advanced_flags_demo.rs1#![allow(clippy::or_fun_call)]
11
12use flag_rs::{CommandBuilder, Flag, FlagConstraint, FlagType, FlagValue};
13
14fn main() {
15 let app = CommandBuilder::new("server")
16 .short("A demo server with advanced configuration options")
17 .long(
18 "This example demonstrates the advanced flag features in flag-rs,
19including choice flags, range validation, file/directory validation,
20and flag constraints.",
21 )
22 .flag(
24 Flag::new("environment")
25 .short('e')
26 .usage("Server environment")
27 .value_type(FlagType::Choice(vec![
28 "development".to_string(),
29 "staging".to_string(),
30 "production".to_string(),
31 ]))
32 .default(FlagValue::String("development".to_string())),
33 )
34 .flag(
36 Flag::new("port")
37 .short('p')
38 .usage("Server port (1024-65535)")
39 .value_type(FlagType::Range(1024, 65535))
40 .default(FlagValue::Int(8080)),
41 )
42 .flag(
44 Flag::new("config")
45 .short('c')
46 .usage("Configuration file path")
47 .value_type(FlagType::File),
48 )
49 .flag(
51 Flag::new("log-dir")
52 .usage("Directory for log files")
53 .value_type(FlagType::Directory)
54 .default(FlagValue::String("/tmp".to_string())),
55 )
56 .flag(
58 Flag::new("tags")
59 .short('t')
60 .usage("Tags for the server (can be specified multiple times)")
61 .value_type(FlagType::StringArray),
62 )
63 .flag(
65 Flag::new("ssl-cert")
66 .usage("SSL certificate file")
67 .value_type(FlagType::File)
68 .constraint(FlagConstraint::RequiredIf("ssl".to_string())),
69 )
70 .flag(
72 Flag::new("ssl-key")
73 .usage("SSL private key file")
74 .value_type(FlagType::File)
75 .constraint(FlagConstraint::RequiredIf("ssl".to_string())),
76 )
77 .flag(
79 Flag::new("ssl")
80 .usage("Enable SSL/TLS")
81 .value_type(FlagType::Bool),
82 )
83 .flag(
85 Flag::new("debug")
86 .short('d')
87 .usage("Enable debug mode")
88 .value_type(FlagType::Bool)
89 .constraint(FlagConstraint::ConflictsWith(vec!["quiet".to_string()])),
90 )
91 .flag(
93 Flag::new("quiet")
94 .short('q')
95 .usage("Quiet mode (minimal output)")
96 .value_type(FlagType::Bool)
97 .constraint(FlagConstraint::ConflictsWith(vec!["debug".to_string()])),
98 )
99 .flag(
101 Flag::new("auth-token")
102 .usage("Authentication token")
103 .value_type(FlagType::String)
104 .constraint(FlagConstraint::Requires(vec!["auth-enabled".to_string()])),
105 )
106 .flag(
108 Flag::new("auth-enabled")
109 .usage("Enable authentication")
110 .value_type(FlagType::Bool),
111 )
112 .flag(
114 Flag::new("name")
115 .short('n')
116 .usage("Server name")
117 .value_type(FlagType::String)
118 .required(),
119 )
120 .run(|ctx| {
121 println!("=== Server Configuration ===\n");
123
124 println!("Server Name: {}", ctx.flag("name").unwrap());
125 println!(
126 "Environment: {}",
127 ctx.flag("environment")
128 .unwrap_or(&"development".to_string())
129 );
130 println!("Port: {}", ctx.flag("port").unwrap_or(&"8080".to_string()));
131
132 if let Some(config) = ctx.flag("config") {
133 println!("Config File: {}", config);
134 }
135
136 println!(
137 "Log Directory: {}",
138 ctx.flag("log-dir").unwrap_or(&"/tmp".to_string())
139 );
140
141 if let Some(tags) = ctx.flag("tags") {
142 println!("Tags: {}", tags);
143 }
144
145 if ctx.flag("ssl").map(|v| v == "true").unwrap_or(false) {
146 println!("\nSSL Configuration:");
147 println!(" Certificate: {}", ctx.flag("ssl-cert").unwrap());
148 println!(" Private Key: {}", ctx.flag("ssl-key").unwrap());
149 }
150
151 if ctx.flag("debug").map(|v| v == "true").unwrap_or(false) {
152 println!("\nDebug mode: ENABLED");
153 } else if ctx.flag("quiet").map(|v| v == "true").unwrap_or(false) {
154 println!("\nQuiet mode: ENABLED");
155 }
156
157 if ctx
158 .flag("auth-enabled")
159 .map(|v| v == "true")
160 .unwrap_or(false)
161 {
162 println!("\nAuthentication: ENABLED");
163 if let Some(token) = ctx.flag("auth-token") {
164 println!(" Token: {}", token);
165 }
166 }
167
168 println!("\nServer would start with the above configuration...");
169 Ok(())
170 })
171 .build();
172
173 println!("=== Advanced Flags Demo ===\n");
174 println!("This demo showcases advanced flag features in flag-rs.\n");
175 println!("Try these commands to see different features:");
176 println!();
177 println!("1. Basic usage with required flag:");
178 println!(
179 " {} --name myserver",
180 std::env::args().next().unwrap_or_default()
181 );
182 println!();
183 println!("2. Choice flag validation:");
184 println!(
185 " {} --name myserver --environment invalid (will fail)",
186 std::env::args().next().unwrap_or_default()
187 );
188 println!(
189 " {} --name myserver --environment production",
190 std::env::args().next().unwrap_or_default()
191 );
192 println!();
193 println!("3. Range validation:");
194 println!(
195 " {} --name myserver --port 80 (will fail - below 1024)",
196 std::env::args().next().unwrap_or_default()
197 );
198 println!(
199 " {} --name myserver --port 3000",
200 std::env::args().next().unwrap_or_default()
201 );
202 println!();
203 println!("4. File/Directory validation:");
204 println!(
205 " {} --name myserver --config ./Cargo.toml",
206 std::env::args().next().unwrap_or_default()
207 );
208 println!(
209 " {} --name myserver --log-dir ./src",
210 std::env::args().next().unwrap_or_default()
211 );
212 println!();
213 println!("5. Flag constraints:");
214 println!(
215 " {} --name myserver --ssl (will fail - missing cert and key)",
216 std::env::args().next().unwrap_or_default()
217 );
218 println!(
219 " {} --name myserver --ssl --ssl-cert cert.pem --ssl-key key.pem",
220 std::env::args().next().unwrap_or_default()
221 );
222 println!(
223 " {} --name myserver --debug --quiet (will fail - conflicts)",
224 std::env::args().next().unwrap_or_default()
225 );
226 println!(
227 " {} --name myserver --auth-token secret (will fail - requires --auth-enabled)",
228 std::env::args().next().unwrap_or_default()
229 );
230 println!();
231 println!("6. View help:");
232 println!(" {} --help", std::env::args().next().unwrap_or_default());
233 println!("\n---\n");
234
235 let args: Vec<String> = std::env::args().skip(1).collect();
236 if let Err(e) = app.execute(args) {
237 eprintln!("{}", e);
238 std::process::exit(1);
239 }
240}