How To Build CLI App In Rust Using Clap

How To Build CLI App In Rust Using Clap

This post is the first of a series of posts that will guide you in building a CLI app in rust using Clap. The ultimate goal is to give readers enough knowledge to develop their own CLI app using rust.

Each part of the series will result in a functional and useful application that will be built upon in future posts. I strongly recommend typing out the code that you see, rather than just copying and pasting the entire block. This is one of the most effective ways to get a better understanding.

If you're new to rust programming language check out my series on Rust

Overview

The CLI application which we are developing in this series will be a file encrypter that will aid in the encryption and decryption of files. We will be encrypting and decrypting files in this application using a specific set of cryptographic libraries. This will have a collection of commands that will help with all the procedures needed to encrypt and decrypt the files.

Commands:

  • Generate: To generate a random key and an IV.
  • Encrypt: Encrypts the given file using a key and an IV.
  • Decrypt: Decrypt the given encrypted file using a key and an IV.

Getting Started

Installation

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Creating New Binary Package

cargo new cryptifer --bin

Screenshot 2022-09-25 at 1.17.42 PM.png

Adding Dependencies

cargo add clap --features derive

Screenshot 2022-09-25 at 3.35.14 PM.png

Setting Up Commands

Create a new file called commands.rs in the src directory and import the clap library into main.rs. Import the newly created file into the main.rs file.

use clap::{Parser, Subcommand};
mod commands;
use commands::*;

Let's structure commands using the Clap library. This application consists of three commands :

  • Generate
  • Encrypt
  • Decrypt

Add application command structure in command.rs. Define a struct Cryptifer is our main command and holds all the subcommands. We are using clap's derive feature that is having macro called Parser that generates parser implementation for the struct which we defined.

Subcommands exist as enum that will be holding necessary flags to take input from cli and aid in performing desired functionality.

use super::*;

#[derive(Debug, Parser)]
#[clap(
    name = "Cryptifer",
    about = "Cryptifer is a CLI Application to Encrypt and Decrypt the file",
    version = "0.0.1"
)]
pub struct Cryptifer {
    #[clap(subcommand)]
    pub command: Commands,
}

#[derive(Debug, Subcommand)]
pub enum Commands {
    /// Generates Keystore to out file given
    #[clap(arg_required_else_help = true)]
    Generate {
        #[clap(short = 'o', long)]
        output_path: String,
    },
    /// Encrypts file specified using keypath
    #[clap(arg_required_else_help = true)]
    Encrypt {
        #[clap(short = 'f', long)]
        file_path: String,
        #[clap(short = 'k', long)]
        key_path: String,
    },
    /// Decrypts file specified using keypath
    #[clap(arg_required_else_help = true)]
    Decrypt {
        #[clap(short = 'f', long)]
        encrypted_file: String,
        #[clap(short = 'k', long)]
        key_path: String,
    },
}

Configure main.rs file.

use clap::{Parser, Subcommand};
mod commands;
use commands::Cryptifer;

fn main() {
    Cryptifer::parse();
}

Let's run our cli. Hurray!! we successfully compiled and run our first CLI application in Rust.

Screenshot 2022-09-28 at 6.14.27 PM.png

⚡ Wrapping Things Up

As mentioned at the beginning, this is the first post of a series that will cover how to build command line applications in rust using clap. If you run into any issues with any part of this tutorial, please leave a comment so that I can update the content to be more clear. If you like this post please do follow me on Hashnode and subscribe to my newsletter for future updates.

Did you find this article valuable?

Support Shreyas K S by becoming a sponsor. Any amount is appreciated!