Skip to content

mdizak/rust-falcon-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GitHub release (latest) License Downloads

Falcon CLI

Efficiently develop fully featured CLI applications in Rust with minimal boilerplate.

Features

  • Command routing with automatic help screens
  • Built-in input functions (text, password, confirmation, multi-select)
  • Table and formatted output displays
  • Parameter and flag validation
  • Progress bars and text editor integration
  • Smart typo correction using Levenshtein distance
  • Multi-level command categories
  • Global flags support

Installation

[dependencies]
falcon-cli = "0.2"

Usage

Define a Command

use falcon_cli::*;

#[derive(Default)]
pub struct CreateDomain {}

impl CliCommand for CreateDomain {
    fn process(&self, req: &CliRequest) -> anyhow::Result<()> {
        req.require_params(1)?;
        req.require_flag("--ip-address")?;

        let domain = &req.args[0];
        let ip = req.get_flag("--ip-address").unwrap();

        if !req.has_flag("-n") && !cli_confirm(&format!("Create {} at {}?", domain, ip)) {
            return Ok(());
        }

        // Your logic here

        cli_sendln!("Domain created: {}", domain);
        Ok(())
    }

    fn help(&self) -> CliHelpScreen {
        let mut help = CliHelpScreen::new(
            "Create Domain",
            "mycli domain create <DOMAIN> --ip-address <IP> [-n]",
            "Create a new domain name"
        );
        help.add_param("DOMAIN", "Domain name to create");
        help.add_flag("--ip-address", "IP address for the domain");
        help.add_flag("-n", "Skip confirmation");
        help
    }
}

Set Up Router

use falcon_cli::*;

fn main() {
    let mut router = CliRouter::new();
    router.app_name("MyApp v1.0");
    router.add::<CreateDomain>("domain create", vec!["dom c"], vec!["--ip-address"]);
    cli_run(&mut router);
}

Run with: cargo run -- domain create example.com --ip-address 1.2.3.4

Categories

Organize commands into groups:

router.add_category("domain", "Domain Names", "Manage domains");
router.add::<CreateDomain>("domain create", vec![], vec!["--ip-address"]);
router.add::<ListDomains>("domain list", vec![], vec![]);

Validation

req.validate_params(vec![
    CliFormat::Email,
    CliFormat::IntegerRange(1..100),
])?;
req.validate_flag("--port", CliFormat::Integer)?;

Available validators: Any, Integer, Decimal, Boolean, Email, Url, File, Directory, IntegerRange, DecimalRange, StringRange, OneOf

User Input

let name = cli_get_input("Name: ", "default");
let password = cli_get_password("Password: ", false);
let strong_pwd = cli_get_new_password(3);  // Strength 0-4

if cli_confirm("Continue?") { /* ... */ }

let choice = cli_get_option("Pick one:", &indexmap! {
    1 => "Option A",
    2 => "Option B",
});

Display

cli_header("My App");

cli_display_table(&["Name", "Age"], &vec![
    vec!["Alice", "30"],
    vec!["Bob", "25"],
]);

let mut bar = cli_progress_bar("Loading", 100);
bar.increment(10);
bar.finish();

cli_sendln!("Hello {}", name);  // Word-wrapped output

Global Flags

router.global("-v", "--verbose", false, "Verbose output");
router.global("-c", "--config", true, "Config file");

if router.has_global("--verbose") { /* ... */ }
if let Some(cfg) = router.get_global("--config") { /* ... */ }

Related Project

If you found this software helpful, check out Cicero - a self-hosted AI assistant focused on protecting personal privacy in the age of AI.

https://cicero.sh/latest

About

Easily and efficiently develop quality and fully featured CLI apps.

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages