flag_rs/
lib.rs

1//! # Flag-rs - A Cobra-inspired CLI Framework for Rust
2//!
3//! Flag-rs is a powerful command-line interface framework for Rust that brings the best features
4//! of Go's Cobra library to the Rust ecosystem. The key differentiator is **dynamic runtime
5//! completions** - unlike other Rust CLI frameworks, Flag-rs can generate completions based on
6//! current system state, making it perfect for tools like `kubectl` that need to complete
7//! resource names from a live API.
8//!
9//! ## Key Features
10//!
11//! - **Dynamic Completions**: Generate completions at runtime based on application state
12//! - **Zero Dependencies**: Pure Rust implementation with no external crates
13//! - **Subcommand Support**: Organize complex CLIs with nested subcommands
14//! - **Flag Inheritance**: Global flags automatically available to all subcommands
15//! - **Shell Completion**: Generate completion scripts for bash, zsh, and fish
16//! - **Colored Output**: Beautiful help messages with automatic TTY detection
17//! - **Flexible Architecture**: Use builder pattern or direct construction
18//! - **Advanced Flag Types**: Choice, Range, File, Directory validation
19//! - **Flag Constraints**: `RequiredIf`, `ConflictsWith`, `Requires` relationships
20//! - **Completion Caching**: Cache expensive completion operations
21//! - **Timeout Protection**: Prevent slow completions from hanging
22//! - **Memory Optimization**: String interning and efficient data structures
23//!
24//! ## Quick Start
25//!
26//! ```rust
27//! use flag_rs::{CommandBuilder, Flag, FlagType, FlagValue};
28//!
29//! let app = CommandBuilder::new("myapp")
30//!     .short("A simple CLI application")
31//!     .long("This is my awesome command-line application that does great things")
32//!     .flag(
33//!         Flag::new("verbose")
34//!             .short('v')
35//!             .usage("Enable verbose output")
36//!             .value_type(FlagType::Bool)
37//!             .default(FlagValue::Bool(false))
38//!     )
39//!     .subcommand(
40//!         CommandBuilder::new("serve")
41//!             .short("Start the server")
42//!             .flag(
43//!                 Flag::new("port")
44//!                     .short('p')
45//!                     .usage("Port to listen on")
46//!                     .value_type(FlagType::Int)
47//!                     .default(FlagValue::Int(8080))
48//!             )
49//!             .run(|ctx| {
50//!                 let verbose = ctx.flag("verbose")
51//!                     .and_then(|s| s.parse::<bool>().ok())
52//!                     .unwrap_or(false);
53
54//!                 let port = ctx.flag("port")
55//!                     .and_then(|s| s.parse::<i64>().ok())
56//!                     .unwrap_or(8080);
57//!
58//!                 if verbose {
59//!                     println!("Starting server on port {}", port);
60//!                 }
61//!                 Ok(())
62//!             })
63//!             .build()
64//!     )
65//!     .build();
66//!
67//! // In main():
68//! // let args: Vec<String> = std::env::args().skip(1).collect();
69//! // if let Err(e) = app.execute(args) {
70//! //     eprintln!("Error: {}", e);
71//! //     std::process::exit(1);
72//! // }
73//! ```
74//!
75//! ## Dynamic Completions
76//!
77//! The killer feature that sets Flag-rs apart from other Rust CLI libraries:
78//!
79//! ```rust
80//! use flag_rs::{CommandBuilder, CompletionResult};
81//!
82//! let cmd = CommandBuilder::new("kubectl")
83//!     .subcommand(
84//!         CommandBuilder::new("get")
85//!             .subcommand(
86//!                 CommandBuilder::new("pods")
87//!                     .arg_completion(|ctx, prefix| {
88//!                         // This runs when the user presses TAB!
89//!                         // In a real app, you'd query the Kubernetes API here
90//!                         let namespace = ctx.flag("namespace")
91//!                             .map(|s| s.as_str())
92//!                             .unwrap_or("default");
93//!
94//!                         let pods = vec!["nginx-abc123", "redis-def456", "postgres-ghi789"];
95//!                         Ok(CompletionResult::new().extend(
96//!                             pods.into_iter()
97//!                                 .filter(|p| p.starts_with(prefix))
98//!                                 .map(String::from)
99//!                         ))
100//!                     })
101//!                     .build()
102//!             )
103//!             .build()
104//!     )
105//!     .build();
106//! ```
107//!
108//! ## Shell Completion Setup
109//!
110//! Add a completion command to enable shell completions:
111//!
112//! ```rust
113//! use flag_rs::{CommandBuilder, Shell};
114//!
115//! fn build_completion_command() -> flag_rs::Command {
116//!     CommandBuilder::new("completion")
117//!         .short("Generate shell completion script")
118//!         .run(|ctx| {
119//!             let shell_name = ctx.args().first()
120//!                 .ok_or(flag_rs::Error::ArgumentParsing("shell name required".to_string()))?;
121//!
122//!             // In a real app, get the root command here
123//!             // let script = match shell_name.as_str() {
124//!             //     "bash" => root_cmd.generate_completion(Shell::Bash),
125//!             //     "zsh" => root_cmd.generate_completion(Shell::Zsh),
126//!             //     "fish" => root_cmd.generate_completion(Shell::Fish),
127//!             //     _ => return Err(flag_rs::Error::ArgumentParsing("unsupported shell".to_string())),
128//!             // };
129//!             // println!("{}", script);
130//!             Ok(())
131//!         })
132//!         .build()
133//! }
134//! ```
135//!
136//! Users can then enable completions:
137//!
138//! ```bash
139//! # Bash
140//! source <(myapp completion bash)
141//!
142//! # Zsh
143//! source <(myapp completion zsh)
144//!
145//! # Fish
146//! myapp completion fish | source
147//! ```
148//!
149//! ## Advanced Flag Types
150//!
151//! Flag-rs now supports advanced flag types with built-in validation:
152//!
153//! ```rust
154//! use flag_rs::{CommandBuilder, Flag, FlagType, FlagValue};
155//!
156//! let cmd = CommandBuilder::new("config")
157//!     .flag(
158//!         Flag::new("environment")
159//!             .value_type(FlagType::Choice(vec![
160//!                 "dev".to_string(),
161//!                 "staging".to_string(),
162//!                 "prod".to_string()
163//!             ]))
164//!     )
165//!     .flag(
166//!         Flag::new("workers")
167//!             .value_type(FlagType::Range(1, 16))
168//!             .default(FlagValue::Int(4))
169//!     )
170//!     .flag(
171//!         Flag::new("config-file")
172//!             .value_type(FlagType::File)
173//!     )
174//!     .build();
175//! ```
176//!
177//! ## Flag Constraints
178//!
179//! Define relationships between flags:
180//!
181//! ```rust
182//! use flag_rs::{Flag, FlagType, FlagConstraint};
183//!
184//! let ssl_cert_flag = Flag::new("ssl-cert")
185//!     .value_type(FlagType::File)
186//!     .constraint(FlagConstraint::RequiredIf("ssl".to_string()));
187//!
188//! let json_flag = Flag::new("json")
189//!     .value_type(FlagType::Bool)
190//!     .constraint(FlagConstraint::ConflictsWith(vec!["xml".to_string()]));
191//! ```
192//!
193//! ## Performance Features
194//!
195//! ### Completion Caching
196//!
197//! Cache expensive completion operations:
198//!
199//! ```rust,ignore
200//! use flag_rs::completion_cache::CompletionCache;
201//! use std::sync::Arc;
202//! use std::time::Duration;
203//!
204//! let cache = Arc::new(CompletionCache::new(Duration::from_secs(5)));
205//! ```
206//!
207//! ### Timeout Protection
208//!
209//! Prevent slow completions from hanging:
210//!
211//! ```rust,ignore
212//! use flag_rs::completion_timeout::make_timeout_completion;
213//! use std::time::Duration;
214//!
215//! let safe_completion = make_timeout_completion(
216//!     Duration::from_millis(100),
217//!     expensive_completion_fn
218//! );
219//! ```
220//!
221//! ## Modular Command Structure
222//!
223//! For larger applications, Flag-rs supports a modular architecture:
224//!
225//! ```rust,ignore
226//! // src/commands/mod.rs
227//! pub fn register_commands(root: &mut flag_rs::Command) {
228//!     // Register each command module
229//!     serve::register(root);
230//!     config::register(root);
231//!     migrate::register(root);
232//! }
233//!
234//! // src/commands/serve.rs
235//! use flag_rs::{CommandBuilder, Flag, FlagType};
236//!
237//! pub fn register(parent: &mut flag_rs::Command) {
238//!     let cmd = CommandBuilder::new("serve")
239//!         .short("Start the application server")
240//!         .flag(
241//!             Flag::new("port")
242//!                 .short('p')
243//!                 .usage("Port to bind to")
244//!                 .value_type(FlagType::Int)
245//!         )
246//!         .run(|ctx| {
247//!             // Server implementation
248//!             Ok(())
249//!         })
250//!         .build();
251//!
252//!     parent.add_command(cmd);
253//! }
254//! ```
255//!
256//! ## Error Handling
257//!
258//! Flag-rs uses idiomatic Rust error handling:
259//!
260//! ```rust
261//! use flag_rs::{CommandBuilder, Error};
262//!
263//! let cmd = CommandBuilder::new("deploy")
264//!     .run(|ctx| {
265//!         let env = ctx.args().first()
266//!             .ok_or(Error::ArgumentParsing("environment required".to_string()))?;
267//!
268//!         if env != "production" && env != "staging" {
269//!             return Err(Error::Validation(
270//!                 format!("unknown environment: {}", env)
271//!             ));
272//!         }
273//!
274//!         Ok(())
275//!     })
276//!     .build();
277//! ```
278
279/// Color support for terminal output
280pub mod color;
281
282/// Core command structures and execution
283pub mod command;
284
285/// Dynamic completion support
286pub mod completion;
287
288/// Runtime context for command execution
289pub mod context;
290
291/// Error types and result handling
292pub mod error;
293
294/// Flag parsing and value types
295pub mod flag;
296
297/// Shell completion script generation
298pub mod shell;
299
300/// Completion format handling
301pub mod completion_format;
302
303/// Completion caching for performance
304pub mod completion_cache;
305
306/// Completion timeout handling
307pub mod completion_timeout;
308
309/// Terminal utilities for enhanced CLI output
310pub mod terminal;
311
312/// Argument validation for commands
313pub mod validator;
314
315/// Command and flag suggestion support
316pub mod suggestion;
317
318/// ActiveHelp system for contextual hints
319pub mod active_help;
320
321/// Memory-efficient completion items
322pub mod completion_item;
323
324/// Memory-optimized completion results
325pub mod completion_optimized;
326
327/// String interning pool for reducing memory usage
328pub mod string_pool;
329
330/// Memory-optimized flag parsing
331pub mod parse_optimized;
332
333// Re-export main types for convenience
334pub use command::{Command, CommandBuilder};
335pub use completion::{CompletionFunc, CompletionResult};
336pub use completion_cache::CompletionCache;
337pub use context::Context;
338pub use error::{Error, Result};
339pub use flag::{Flag, FlagConstraint, FlagType, FlagValue};
340pub use shell::Shell;
341pub use validator::ArgValidator;