error_handling_demo/
error_handling_demo.rs

1//! Demonstrates enhanced error handling with colored output and suggestions
2//!
3//! This example shows how flag-rs provides helpful error messages with:
4//! - Clear error formatting
5//! - Command suggestions for typos
6//! - Helpful hints for common mistakes
7//! - Validation error details
8
9use 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}