dharanad / kvs

0 stars 0 forks source link

[rampup] clap #1

Open dharanad opened 10 months ago

dharanad commented 10 months ago

Crates like clap make it super easy to write your own CLI tool in Rust by making it as easy as possible using structs and macros via the Derive feature, as well as offering a more low-level option with the Builder API.

Adding clap are dependency

cargo add clap -F derive

Parser macro

The clap::Parser derive macro, which automatically generates all of the functions that we need to be able to use the struct as a parser. Initially when we load the program up and use Cli::parse(), it will take the arguments from whatever is in std::env::args_os - our environment arguments that we have given it.

use clap::{Parser, Subcommand};

#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
    name: String
}

fn main() {
    let cli = Cli::parse();

    println!("Hello, {}!", cli.name);
}

Clap CLI Looping

For this purpose, the clap::Parser trait also has the try_parse_from function where it will try to parse CLI commands from a variable that implements Into - for this case, we can use a vector as they can be iterated on.

fn main() {
    loop {
        let mut buf = String::from(crate_name!());

        std::io::stdin().read_line(&mut buf).expect("Couldn't parse stdin");
        let line = buf.trim();
        let cli = shlex::split(line).ok_or("error: Invalid quoting").unwrap();

        println!("{:?}" , cli);

        match Args::try_parse_from(args.iter()).map_err(|e| e.to_string()) {
            Ok(cli) => {
                match cli.cmd {
                    Commands::Get(value) => get_something(value),
                    Commands::Set{key, value, is_true} => set_something(key, value, is_true)
               }
            }
            Err(_) => println!("That's not a valid command!");
       };
    }
}