error_handling_demo/
error_handling_demo.rs1use flag_rs::validator::ArgValidator;
10use flag_rs::{CommandBuilder, Error, Flag, FlagType};
11
12fn main() {
13 let app = CommandBuilder::new("error-demo")
14 .short("Demonstrates error handling")
15 .long("This example shows various error scenarios and how flag-rs handles them")
16 .subcommand(
17 CommandBuilder::new("deploy")
18 .short("Deploy the application")
19 .args(ArgValidator::ExactArgs(1))
20 .run(|ctx| {
21 let env = ctx.args().first().unwrap();
22 if !["dev", "staging", "production"].contains(&env.as_str()) {
23 return Err(Error::Validation(format!(
24 "invalid environment '{}', must be one of: dev, staging, production",
25 env
26 )));
27 }
28 println!("Deploying to {}", env);
29 Ok(())
30 })
31 .build(),
32 )
33 .subcommand(
34 CommandBuilder::new("serve")
35 .short("Start the server")
36 .flag(
37 Flag::new("port")
38 .short('p')
39 .usage("Port to listen on")
40 .value_type(FlagType::Int)
41 .required(),
42 )
43 .run(|ctx| {
44 let port = ctx.flag("port").unwrap();
45 println!("Server starting on port {}", port);
46 Ok(())
47 })
48 .build(),
49 )
50 .subcommand(
51 CommandBuilder::new("migrate")
52 .short("Run database migrations")
53 .subcommand(
54 CommandBuilder::new("up")
55 .short("Run pending migrations")
56 .run(|_| {
57 println!("Running migrations...");
58 Ok(())
59 })
60 .build(),
61 )
62 .subcommand(
63 CommandBuilder::new("down")
64 .short("Rollback migrations")
65 .args(ArgValidator::MaximumArgs(1))
66 .run(|ctx| {
67 let steps = ctx
68 .args()
69 .first()
70 .and_then(|s| s.parse::<u32>().ok())
71 .unwrap_or(1);
72 println!(
73 "Rolling back {} migration{}",
74 steps,
75 if steps == 1 { "" } else { "s" }
76 );
77 Ok(())
78 })
79 .build(),
80 )
81 .build(),
82 )
83 .subcommand(
84 CommandBuilder::new("config")
85 .short("Manage configuration")
86 .aliases(vec!["cfg", "conf"])
87 .run(|_| {
88 println!("Configuration management");
89 Ok(())
90 })
91 .build(),
92 )
93 .build();
94
95 println!("=== Error Handling Demo ===\n");
96 println!("This demo shows how flag-rs handles various error scenarios.\n");
97 println!("Try these commands to see different error types:\n");
98 println!(
99 "1. {} deploi (typo - will show suggestions)",
100 std::env::args().next().unwrap_or_default()
101 );
102 println!(
103 "2. {} deploy (missing required argument)",
104 std::env::args().next().unwrap_or_default()
105 );
106 println!(
107 "3. {} deploy dev staging (too many arguments)",
108 std::env::args().next().unwrap_or_default()
109 );
110 println!(
111 "4. {} deploy test (invalid environment)",
112 std::env::args().next().unwrap_or_default()
113 );
114 println!(
115 "5. {} serve (missing required flag)",
116 std::env::args().next().unwrap_or_default()
117 );
118 println!(
119 "6. {} serve -p abc (invalid flag value)",
120 std::env::args().next().unwrap_or_default()
121 );
122 println!(
123 "7. {} migrate (subcommand required)",
124 std::env::args().next().unwrap_or_default()
125 );
126 println!(
127 "8. {} confi (typo - will suggest 'config')",
128 std::env::args().next().unwrap_or_default()
129 );
130 println!("\n---\n");
131
132 let args: Vec<String> = std::env::args().skip(1).collect();
133 if let Err(e) = app.execute(args) {
134 eprintln!("{}", e);
135 std::process::exit(1);
136 }
137}