Alfonso's Website
5 min read

Build a Command Line Application in Rust

Command line applications (CLIs) are a useful way to interact with your computer and perform tasks without a graphical interface. They are especially useful for automating tasks and writing scripts.

In this tutorial, we'll learn how to create a command line application in Rust that hypothetically reads a given file path and stores its contents in a database. To do this, we'll be using the clap crate, clap is a command line argument parser that simplifies the process of parsing arguments and options passed to your CLI.

First, we'll need to add clap to our Cargo.toml file, to do that run the following command in your console:

cargo add clap --features derive

Alternatively you can manually add the dependency:

[dependencies]
clap = { version = "4.0.32", features = ["derive"] }

Next, create a new Rust file (main.rs) and add the following code:

use clap::Parser;

/// Read the input file and store the contents in a database
#[derive(Parser, Debug)]
#[command(author = "Alfonso Bribiesca", version, about, long_about = None)]
struct Args {
    /// File path to read
    input_file: String,

    /// Create a new table
    #[arg(short, long, default_value = "false")]
    create_table: bool,

    /// Drop the table
    #[arg(short, long, default_value = "false")]
    drop_table: bool,

    /// Table name
    #[arg(short, long="table", default_value = "")]
    table_name: String,
}

This code is for a CLI for reading an input file and storing its contents in a database.

It defines a struct called Args that represents the arguments and options passed to the CLI. The #[derive(Parser, Debug)] attribute generates code for parsing the command line arguments and options and for printing the values of the Args struct. The #[command(author = "Alfonso Bribiesca", version, about, long_about = None)] attribute provides metadata about the CLI, such as the author's name and a brief description of the CLI.

The Args struct contains four fields:

  • input_file: a String representing the input file passed as the first argument to the CLI.
  • create_table: a bool representing whether the create_table option is set. If this option is set, a new table will be hypothetically created in the database.
  • drop_table: a bool representing whether the drop_table option is set. If this option is set, the table will be hypothetically dropped (deleted) from the database.
  • table_name: a String representing the name of the table that hypothetically will be used to name the database table.

To define the arguments and options for our CLI, we use the #[arg(short, long, value_name = "VALUE", index = INDEX, default_value = "DEFAULT")] attribute. The short and long arguments define the short and long forms of the option, respectively. The default_value argument specifies a default value for the option if it is not provided.

Now let's add the main function to our code:

fn main() {
    let args = Args::parse();

    // Print all args
    println!("{:#?}", args);
}

In the main function, we call the Args::parse() method to parse the command line arguments and options. This method returns an Args struct containing the values of the arguments and options passed to the CLI.

We can then print the values of the Args struct using the println! macro. This is useful for debugging and understanding the values passed to the CLI.

With this, you will have a basic CLI. Now it's up to you to add the actual functionality.

You can test the application by running the command:

cargo run -- <arguments>

Replace <arguments> with the arguments and options you want to pass to the CLI. For example:

cargo run -- --drop-table --table=my-table /path/to/file.xls

It should return the following output:

Args {
    input_file: "/ath/to/file.xls",
    create_table: false,
    drop_table: true,
    table_name: "my-table",
}

You can also use the --help option to see a list of available options and the summary of your application.

cargo run -- --help

Read the input file and store the contents in a database

Usage: parser [OPTIONS] <INPUT_FILE>

Arguments:
  <INPUT_FILE>  First positional argument is the input file

Options:
  -c, --create-table        Create a new table
  -d, --drop-table          Drop the table
  -t, --table <TABLE_NAME>  Table name [default: ]
  -h, --help                Print help information
  -V, --version             Print version information

I hope this helps! Let me know if you have any questions.