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;