Expand description
§Flag-rs - A Cobra-inspired CLI Framework for Rust
Flag-rs is a powerful command-line interface framework for Rust that brings the best features
of Go’s Cobra library to the Rust ecosystem. The key differentiator is dynamic runtime
completions - unlike other Rust CLI frameworks, Flag-rs can generate completions based on
current system state, making it perfect for tools like kubectl that need to complete
resource names from a live API.
§Key Features
- Dynamic Completions: Generate completions at runtime based on application state
- Zero Dependencies: Pure Rust implementation with no external crates
- Subcommand Support: Organize complex CLIs with nested subcommands
- Flag Inheritance: Global flags automatically available to all subcommands
- Shell Completion: Generate completion scripts for bash, zsh, and fish
- Colored Output: Beautiful help messages with automatic TTY detection
- Flexible Architecture: Use builder pattern or direct construction
- Advanced Flag Types: Choice, Range, File, Directory validation
- Flag Constraints:
RequiredIf,ConflictsWith,Requiresrelationships - Completion Caching: Cache expensive completion operations
- Timeout Protection: Prevent slow completions from hanging
- Memory Optimization: String interning and efficient data structures
§Quick Start
use flag_rs::{CommandBuilder, Flag, FlagType, FlagValue};
let app = CommandBuilder::new("myapp")
.short("A simple CLI application")
.long("This is my awesome command-line application that does great things")
.flag(
Flag::new("verbose")
.short('v')
.usage("Enable verbose output")
.value_type(FlagType::Bool)
.default(FlagValue::Bool(false))
)
.subcommand(
CommandBuilder::new("serve")
.short("Start the server")
.flag(
Flag::new("port")
.short('p')
.usage("Port to listen on")
.value_type(FlagType::Int)
.default(FlagValue::Int(8080))
)
.run(|ctx| {
let verbose = ctx.flag("verbose")
.and_then(|s| s.parse::<bool>().ok())
.unwrap_or(false);
let port = ctx.flag("port")
.and_then(|s| s.parse::<i64>().ok())
.unwrap_or(8080);
if verbose {
println!("Starting server on port {}", port);
}
Ok(())
})
.build()
)
.build();
// In main():
// let args: Vec<String> = std::env::args().skip(1).collect();
// if let Err(e) = app.execute(args) {
// eprintln!("Error: {}", e);
// std::process::exit(1);
// }§Dynamic Completions
The killer feature that sets Flag-rs apart from other Rust CLI libraries:
use flag_rs::{CommandBuilder, CompletionResult};
let cmd = CommandBuilder::new("kubectl")
.subcommand(
CommandBuilder::new("get")
.subcommand(
CommandBuilder::new("pods")
.arg_completion(|ctx, prefix| {
// This runs when the user presses TAB!
// In a real app, you'd query the Kubernetes API here
let namespace = ctx.flag("namespace")
.map(|s| s.as_str())
.unwrap_or("default");
let pods = vec!["nginx-abc123", "redis-def456", "postgres-ghi789"];
Ok(CompletionResult::new().extend(
pods.into_iter()
.filter(|p| p.starts_with(prefix))
.map(String::from)
))
})
.build()
)
.build()
)
.build();§Shell Completion Setup
Add a completion command to enable shell completions:
use flag_rs::{CommandBuilder, Shell};
fn build_completion_command() -> flag_rs::Command {
CommandBuilder::new("completion")
.short("Generate shell completion script")
.run(|ctx| {
let shell_name = ctx.args().first()
.ok_or(flag_rs::Error::ArgumentParsing("shell name required".to_string()))?;
// In a real app, get the root command here
// let script = match shell_name.as_str() {
// "bash" => root_cmd.generate_completion(Shell::Bash),
// "zsh" => root_cmd.generate_completion(Shell::Zsh),
// "fish" => root_cmd.generate_completion(Shell::Fish),
// _ => return Err(flag_rs::Error::ArgumentParsing("unsupported shell".to_string())),
// };
// println!("{}", script);
Ok(())
})
.build()
}Users can then enable completions:
# Bash
source <(myapp completion bash)
# Zsh
source <(myapp completion zsh)
# Fish
myapp completion fish | source§Advanced Flag Types
Flag-rs now supports advanced flag types with built-in validation:
use flag_rs::{CommandBuilder, Flag, FlagType, FlagValue};
let cmd = CommandBuilder::new("config")
.flag(
Flag::new("environment")
.value_type(FlagType::Choice(vec![
"dev".to_string(),
"staging".to_string(),
"prod".to_string()
]))
)
.flag(
Flag::new("workers")
.value_type(FlagType::Range(1, 16))
.default(FlagValue::Int(4))
)
.flag(
Flag::new("config-file")
.value_type(FlagType::File)
)
.build();§Flag Constraints
Define relationships between flags:
use flag_rs::{Flag, FlagType, FlagConstraint};
let ssl_cert_flag = Flag::new("ssl-cert")
.value_type(FlagType::File)
.constraint(FlagConstraint::RequiredIf("ssl".to_string()));
let json_flag = Flag::new("json")
.value_type(FlagType::Bool)
.constraint(FlagConstraint::ConflictsWith(vec!["xml".to_string()]));§Performance Features
§Completion Caching
Cache expensive completion operations:
use flag_rs::completion_cache::CompletionCache;
use std::sync::Arc;
use std::time::Duration;
let cache = Arc::new(CompletionCache::new(Duration::from_secs(5)));§Timeout Protection
Prevent slow completions from hanging:
use flag_rs::completion_timeout::make_timeout_completion;
use std::time::Duration;
let safe_completion = make_timeout_completion(
Duration::from_millis(100),
expensive_completion_fn
);§Modular Command Structure
For larger applications, Flag-rs supports a modular architecture:
// src/commands/mod.rs
pub fn register_commands(root: &mut flag_rs::Command) {
// Register each command module
serve::register(root);
config::register(root);
migrate::register(root);
}
// src/commands/serve.rs
use flag_rs::{CommandBuilder, Flag, FlagType};
pub fn register(parent: &mut flag_rs::Command) {
let cmd = CommandBuilder::new("serve")
.short("Start the application server")
.flag(
Flag::new("port")
.short('p')
.usage("Port to bind to")
.value_type(FlagType::Int)
)
.run(|ctx| {
// Server implementation
Ok(())
})
.build();
parent.add_command(cmd);
}§Error Handling
Flag-rs uses idiomatic Rust error handling:
use flag_rs::{CommandBuilder, Error};
let cmd = CommandBuilder::new("deploy")
.run(|ctx| {
let env = ctx.args().first()
.ok_or(Error::ArgumentParsing("environment required".to_string()))?;
if env != "production" && env != "staging" {
return Err(Error::Validation(
format!("unknown environment: {}", env)
));
}
Ok(())
})
.build();Re-exports§
pub use command::Command;pub use command::CommandBuilder;pub use completion::CompletionFunc;pub use completion::CompletionResult;pub use completion_cache::CompletionCache;pub use context::Context;pub use error::Error;pub use error::Result;pub use flag::Flag;pub use flag::FlagConstraint;pub use flag::FlagType;pub use flag::FlagValue;pub use shell::Shell;pub use validator::ArgValidator;
Modules§
- active_
help - ActiveHelp system for contextual hints ActiveHelp system for contextual hints during completion
- color
- Color support for terminal output Simple ANSI color support with zero dependencies
- command
- Core command structures and execution Command execution and management
- completion
- Dynamic completion support Dynamic shell completion support
- completion_
cache - Completion caching for performance Caching system for expensive completion operations
- completion_
format - Completion format handling Completion format handling for different shells
- completion_
item - Memory-efficient completion items Memory-efficient completion item structure
- completion_
optimized - Memory-optimized completion results Memory-optimized completion result structure
- completion_
timeout - Completion timeout handling Timeout handling for completion functions
- context
- Runtime context for command execution Context for passing data between commands
- error
- Error types and result handling Error types for the flag framework
- flag
- Flag parsing and value types Flag system for command-line argument parsing
- parse_
optimized - Memory-optimized flag parsing Memory-optimized flag parsing
- shell
- Shell completion script generation Shell completion script generation
- string_
pool - String interning pool for reducing memory usage String interning pool for reducing memory usage
- suggestion
- Command and flag suggestion support Command and flag suggestion support
- terminal
- Terminal utilities for enhanced CLI output Terminal utilities for enhanced CLI output
- validator
- Argument validation for commands Argument validation for commands