Skip to content
/ fli Public

A library for creating CLI apps in rust inspired by the like of commander.js

License

Notifications You must be signed in to change notification settings

codad5/fli

Folders and files

NameName
Last commit message
Last commit date
Oct 13, 2024
Nov 25, 2023
Oct 14, 2024
Oct 14, 2024
Jan 19, 2024
Oct 14, 2024
Oct 14, 2024
Oct 13, 2024
Oct 14, 2024
Oct 13, 2024
May 25, 2023

Repository files navigation

FLI

A library for creating command line apps in rust inspired by the like of commander.js

NOTE: Check out sample code

Changes

For stable changes check the CHANGELOG.md file

For unstable changes check the CHANGELOG.md file

use fli::{Fli, init_fli_from_toml};

fn main(){
    let mut app : Fli = init_fli_from_toml!(); // using the toml file
    app.option("-n --name, <>", "Name to call you", |x : &Fli| {});
    app.option("-g --greet", "greeting", |x : &Fli| {
        match x.get_values("name".to_owned() /* passing (--name, -n or n) would work*/){
            Ok(value) => {
                println!("Good day {?}", value[0])
            },
            Err(_) => {},
        }
    });
    // required for the app  to work 
    app.run();
}

then run it like this

$ cargo run -- -g -n james
Good day james

Getting started

Installtion

cargo add fli

OR

[dependencies]
fli = "0.0.5"

Import

extern crate fli;
use fli::Fli;
fn main(){
    println!("Happy Coding");
}

Create an App Instance

fn main(){
    let mut app = init_fli_from_toml!(); // to init from your cargo.toml file
}

OR

fn main(){
    let mut app = Fli::init("app-name", "an app description");
    app.set_version("0.0.1");
}

Adding Options

fn main(){
    let mut app = init_fli_from_toml!();
    app.option("-g --greet", "to make a greeting", greet);
    app.option("-n --name, <>", "to set your name", |x|{});
}

// callback for the greet param
fn greet(x: &Fli){
    match x.get_values("--name".to_owned()){
        Ok(option) => {
            println!("Good day {?}", v[0]);
        },
        Err(_) => {},
    }
}

Run your app

fn main(){
    //... other code
    app.run();
}

Adding a new Command Set

You can also add a new command set using the command method

fn main(){
    let mut app = init_fli_from_toml!();
    app.command("greet", "An app that respects")
    .default(greet)
    .allow_inital_no_param_values(false)
    .option("-n --name, <>", "To print your name along side", greet)
    .option("-t --time, []", "For time based Greeting", greet);
    app.run();
}

fn greet(x){ /*code to greet "*/ }

Then you would run the command like this

$ cargo run -- greet -n "codad5" 
> Hello Codad5

Doing it in a procedual way

Like commander.js you can also do it in a procedual way

use fli::Fli;

fn main(){
    //  doing it procedual way
    let mut app = init_fli_from_toml!();
    let moveCommand = app.command("move", "move files");
    // the [...] means accept optional multiple
    moveCommand.option("-p --path, <...>", "path to files to be moved", move_file);
    app.option("-g --greet",  "to make a greeting", |x|{});
    app.option("-n --name, <>", "to set your name", |x|{});
    app.run();

    if app.is_passed("--greet"){
        if app.has_a_value("-n"){/* greet person with name*/}
        else { /* freet without name*/ }
    }
}

Explaining all app : Fli methods

Note:

All app : Fli methods are avaliable as app : &Fli methods

  • app.option(arg_and_data, callback) : This method takes in 2 param

    • First arg_and_data : This is a format template of how the avaliable arguments for a command would be being in a format -a --arg or -a --arg, data where -a is the short form of the argument and --arg is the long form of the argument. --data is the acceptable data type and it is seperated by a comma , , if not passed then the arg does not need a data type
    symbol meaning
    [] This means it needs one optional data
    <> This means it needs one required data
    [...] This means it can take in many optional data
    <...> This means it needs at least one data, can take more
  • app.commad(command_name) : This is to create a new command with its own option and param like

  • app.default(callback) : The default callback incase no args or command is being passed but a no_param_value is being passed

  • app.allow_duplicate_callback(bool) : To prevent duplicate callbacks as a result of same callback of an arg or as a result of the arg been passed multiple times

    • True : Turns it on i.e the code below would work fine
    $ myapp "some ran value"
  • app.allow_inital_no_param_values(bool) : This is to allow values to a command with no params

  • app.run() (!important) : To run the app ,

  • app.has_a_value(arg_flag) : Check if an arg has a value

  • app.get_values(arg_flag) : get the value(s) of an expect required param, this returns a Result Type with a vector of string as the Ok value Vec<String> and &str as the error value

NOTE the method get_values would return the Err Enum if the arg does not expect or require a value

  • app.is_passed(bool) : Check if an arg flag is passed.

NOTE : using the methods has_a_value, get_values and is_passed you can pass -n , --name , n , name and they would all return same expected value

  • app.get_arg_at(u8) : Get Arg at a specific position

NOTE : The runner is not included as part of the arg list . ie if a command like this my-app > greet > hello exist the position 1 for the command greet is greet and not my-app

  • app.print_help(message) : Prints a well descriptive message.

Printing default help thisGet the app general help option

$ my-app --help

Get the move command help option

$ my-app move --help # a new command called