help_formatting_demo/
help_formatting_demo.rs

1//! Demo of enhanced help formatting
2//!
3//! Run with: cargo run --example `help_formatting_demo` -- --help
4
5use flag_rs::{CommandBuilder, Flag, FlagConstraint, FlagType, FlagValue};
6
7fn main() {
8    let app = CommandBuilder::new("helpdemo")
9        .short("A demo of enhanced help formatting")
10        .long("This is a comprehensive demonstration of the enhanced help formatting system in flag-rs. \
11               It shows how help text is beautifully formatted with proper grouping, constraint \
12               information, and visual hierarchy.")
13        .group_id("utilities")
14        .example("helpdemo config --format=yaml --output=config.yaml")
15        .example("helpdemo process --workers=4 --verbose data.json")
16        .example("helpdemo serve --port=8080 --ssl --ssl-cert=cert.pem")
17        .flag(
18            Flag::new("verbose")
19                .short('v')
20                .value_type(FlagType::Bool)
21                .usage("Enable verbose output (can be repeated for more verbosity)"),
22        )
23        .flag(
24            Flag::new("config")
25                .short('c')
26                .value_type(FlagType::File)
27                .default(FlagValue::String("~/.config/app.toml".to_string()))
28                .usage("Configuration file path"),
29        )
30        .flag(
31            Flag::new("workers")
32                .short('w')
33                .value_type(FlagType::Range(1, 16))
34                .default(FlagValue::Int(4))
35                .usage("Number of worker threads"),
36        )
37        .flag(
38            Flag::new("timeout")
39                .short('t')
40                .value_type(FlagType::Int)
41                .default(FlagValue::Int(30))
42                .usage("Request timeout in seconds"),
43        )
44        .subcommand(
45            CommandBuilder::new("config")
46                .short("Manage configuration")
47                .long("The config command allows you to view, edit, and validate configuration files. \
48                      It supports multiple output formats and can merge configurations from various sources.")
49                .alias("cfg")
50                .alias("conf")
51                .example("helpdemo config show")
52                .example("helpdemo config validate --strict")
53                .flag(
54                    Flag::new("format")
55                        .short('f')
56                        .value_type(FlagType::Choice(vec![
57                            "json".to_string(),
58                            "yaml".to_string(),
59                            "toml".to_string(),
60                            "ini".to_string(),
61                        ]))
62                        .default(FlagValue::String("yaml".to_string()))
63                        .usage("Configuration file format"),
64                )
65                .flag(
66                    Flag::new("output")
67                        .short('o')
68                        .value_type(FlagType::String)
69                        .required()
70                        .usage("Output file path"),
71                )
72                .flag(
73                    Flag::new("merge")
74                        .value_type(FlagType::StringArray)
75                        .usage("Additional config files to merge"),
76                )
77                .flag(
78                    Flag::new("strict")
79                        .value_type(FlagType::Bool)
80                        .usage("Enable strict validation mode"),
81                )
82                .subcommand(
83                    CommandBuilder::new("show")
84                        .short("Display current configuration")
85                        .run(|_| Ok(()))
86                        .build(),
87                )
88                .subcommand(
89                    CommandBuilder::new("validate")
90                        .short("Validate configuration syntax")
91                        .run(|_| Ok(()))
92                        .build(),
93                )
94                .build(),
95        )
96        .subcommand(
97            CommandBuilder::new("process")
98                .short("Process data files")
99                .group_id("operations")
100                .flag(
101                    Flag::new("input")
102                        .short('i')
103                        .value_type(FlagType::File)
104                        .required()
105                        .usage("Input data file"),
106                )
107                .flag(
108                    Flag::new("output")
109                        .short('o')
110                        .value_type(FlagType::String)
111                        .required()
112                        .usage("Output file path"),
113                )
114                .flag(
115                    Flag::new("format")
116                        .short('f')
117                        .value_type(FlagType::Choice(vec![
118                            "csv".to_string(),
119                            "json".to_string(),
120                            "parquet".to_string(),
121                        ]))
122                        .usage("Output format"),
123                )
124                .flag(
125                    Flag::new("compress")
126                        .value_type(FlagType::Bool)
127                        .usage("Compress output"),
128                )
129                .flag(
130                    Flag::new("compression-level")
131                        .value_type(FlagType::Range(1, 9))
132                        .default(FlagValue::Int(6))
133                        .constraint(FlagConstraint::RequiredIf("compress".to_string()))
134                        .usage("Compression level"),
135                )
136                .run(|_| Ok(()))
137                .build(),
138        )
139        .subcommand(
140            CommandBuilder::new("serve")
141                .short("Start the server")
142                .group_id("operations")
143                .flag(
144                    Flag::new("port")
145                        .short('p')
146                        .value_type(FlagType::Range(1, 65535))
147                        .default(FlagValue::Int(8080))
148                        .usage("Port to listen on"),
149                )
150                .flag(
151                    Flag::new("host")
152                        .short('h')
153                        .value_type(FlagType::String)
154                        .default(FlagValue::String("127.0.0.1".to_string()))
155                        .usage("Host to bind to"),
156                )
157                .flag(
158                    Flag::new("ssl")
159                        .value_type(FlagType::Bool)
160                        .usage("Enable SSL/TLS"),
161                )
162                .flag(
163                    Flag::new("ssl-cert")
164                        .value_type(FlagType::File)
165                        .constraint(FlagConstraint::RequiredIf("ssl".to_string()))
166                        .usage("SSL certificate file"),
167                )
168                .flag(
169                    Flag::new("ssl-key")
170                        .value_type(FlagType::File)
171                        .constraint(FlagConstraint::RequiredIf("ssl".to_string()))
172                        .usage("SSL private key file"),
173                )
174                .flag(
175                    Flag::new("http2")
176                        .value_type(FlagType::Bool)
177                        .constraint(FlagConstraint::Requires(vec!["ssl".to_string()]))
178                        .usage("Enable HTTP/2 support"),
179                )
180                .flag(
181                    Flag::new("debug")
182                        .short('d')
183                        .value_type(FlagType::Bool)
184                        .constraint(FlagConstraint::ConflictsWith(vec!["production".to_string()]))
185                        .usage("Enable debug mode"),
186                )
187                .flag(
188                    Flag::new("production")
189                        .value_type(FlagType::Bool)
190                        .usage("Enable production mode"),
191                )
192                .run(|_| Ok(()))
193                .build(),
194        )
195        .build();
196
197    println!("This example demonstrates enhanced help formatting.");
198    println!("Try these commands to see different help layouts:\n");
199    println!("  # Main help with command groups");
200    println!("  cargo run --example help_formatting_demo -- --help\n");
201
202    println!("  # Subcommand help with required flags");
203    println!("  cargo run --example help_formatting_demo -- config --help\n");
204
205    println!("  # Subcommand with flag constraints");
206    println!("  cargo run --example help_formatting_demo -- serve --help\n");
207
208    let args: Vec<String> = std::env::args().skip(1).collect();
209    if !args.is_empty() {
210        if let Err(e) = app.execute(args) {
211            eprintln!("{}", e);
212            std::process::exit(1);
213        }
214    }
215}