{"id":20834,"date":"2024-02-21T09:32:13","date_gmt":"2024-02-21T14:32:13","guid":{"rendered":"https:\/\/qxf2.com\/blog\/?p=20834"},"modified":"2024-03-05T00:52:13","modified_gmt":"2024-03-05T05:52:13","slug":"brief-introduction-to-clap","status":"publish","type":"post","link":"https:\/\/qxf2.com\/blog\/brief-introduction-to-clap\/","title":{"rendered":"Crafting Rust CLI Applications: A Journey with Clap Crate"},"content":{"rendered":"<p>At <a href=\"https:\/\/qxf2.com\/?utm_source=Clap_in_Rust&amp;utm_medium=click&amp;utm_campaign=From%20blog\" rel=\"noopener\" target=\"_blank\">Qxf2<\/a>, our ongoing efforts involve delving into popular Rust crates and crafting tutorials to facilitate seamless adoption and utilization of these crates. As part of this undertaking, we turned our attention to the <a href=\"https:\/\/crates.io\/crates\/clap\" target=\"_blank\" rel=\"noopener\">Clap<\/a> crate, recognizing its significance as a valuable library for parsing command line arguments in Rust.<br \/>\nThis blog post aims to provide you with a comprehensive introduction to Clap, guiding you through the process of integrating it into your project, building your inaugural Clap application, and delving into various additional features it offers.<\/p>\n<h4>What is Clap and why it rocks?<\/h4>\n<p>Clap is an awesome rust library for parsing command line arguments in console applications. Just tell Clap what&#8217;s valid, and it takes care of the rest. No need to sweat the details. Another reason as to why Clap rocks is that it automatically adds version and help switches without you lifting a finger.<br \/>\nOnce Clap decodes the user&#8217;s input, it provides you with the matches and values. If there&#8217;s an issue with the input, Clap has your back \u2013 it kindly points out the hiccup and exits gracefully, ensuring a smooth user experience.<\/p>\n<h4>Integrating Clap into Your Project<\/h4>\n<p>Create a Cargo Project:<br \/>\n1. Open a terminal and navigate to the directory where you want to create your new project. Run the following command to initiate a new Cargo project:<\/p>\n<pre lang=\"rust\">cargo new your_project_name\r\n<\/pre>\n<p>Replace your_project_name with the desired name for your project.<\/p>\n<p>2. To include Clap in your project, simply add the following to your project&#8217;s <code>Cargo.toml<\/code> file:<\/p>\n<pre lang=\"rust\">[dependencies]\r\nclap = { version = \"4.4.6\", features = [\"derive\"] }\r\n<\/pre>\n<p>This snippet configures Clap as a dependency, incorporating its derive features into your project.<\/p>\n<p>3. Since our project is going to have multiple binaries we need to create an <code>src\/bin<\/code> directory, where we will place our executables.<\/p>\n<p>4. Within the bin directory, include a new Rust file (e.g., default_clap.rs) that will be utilized for crafting our initial example<\/p>\n<h4>Your first Clap program<\/h4>\n<p>Now that we&#8217;ve set up our project and integrated Clap as a dependency, let&#8217;s dive into creating your first Clap program. We will create a simple program that takes a user-inputted number and compute both the square and cube of this number.<br \/>\n1. Open the Rust file you created in the &#8220;bin&#8221; directory (e.g., `default_clap.rs`) and start by importing the necessary modules:<\/p>\n<pre lang=\"rust\">use clap::{Arg};\r\n<\/pre>\n<p>2. Define a struct called Args representing the command-line arguments.<\/p>\n<pre lang=\"rust\">#[derive(Parser, Debug)]\r\n#[command(author, version, about)]\r\nstruct Args {\r\n    #[arg(short, long)]\r\n    number: f64,\r\n}\r\n<\/pre>\n<p>The <code>#[arg(short, long)]<\/code> attribute defines a command-line argument named number with short and long options.<\/p>\n<p>3. Next, lets parse the Command Line Arguments<\/p>\n<pre lang=\"rust\">let args = Args::parse();\r\n<\/pre>\n<p>Here, we use the generated parse method from the Parser trait to parse command-line arguments into the <code>Args<\/code> struct.<\/p>\n<p>4. Now, lets calculate the square and cube of the provided number using simple arithmetic operations.<\/p>\n<pre lang=\"rust\">let square = args.number * args.number;\r\nlet cube = args.number * args.number * args.number;\r\n<\/pre>\n<p>5. Finally, we can print out the results<\/p>\n<pre lang=\"rust\">println!(\"Number: {}\", args.number);\r\nprintln!(\"Square of number: {}\", square);\r\nprintln!(\"Cube of number: {}\", cube);\r\n<\/pre>\n<p>6. Putting it all together<\/p>\n<pre lang=\"rust\">use clap::Parser;\r\n\r\n\/\/\/ Define a struct to represent command line arguments using Clap's derive attribute\r\n\/\/\/ The struct will have built-in help, version, and author information\r\n#[derive(Parser, Debug)]\r\n#[command(author, version, about)]\r\nstruct Args {\r\n    \/\/\/ The number for which to calculate square and cube\r\n    #[arg(short, long)]\r\n    number: f64,\r\n}\r\n\r\nfn main() {\r\n    \/\/ Parse the command line arguments using the generated Args struct\r\n    let args = Args::parse();\r\n\r\n    \/\/ Calculate the square and cube of the provided number\r\n    let square = args.number * args.number;\r\n    let cube = args.number * args.number * args.number;\r\n\r\n    \/\/ Display the results to the user\r\n    println!(\"Number: {}\", args.number);\r\n    println!(\"Square of number: {}\", square);\r\n    println!(\"Cube of number: {}\", cube);\r\n}\r\n<\/pre>\n<h4>Running Your Clap Program<\/h4>\n<p>Now that you&#8217;ve crafted your first Clap program, it&#8217;s time to run a test to see it in action. Follow these steps to execute the program using the Cargo command:<\/p>\n<p>1. Open a terminal window and navigate to your project&#8217;s root directory.<br \/>\n2. Run the following command to build and run your Clap program, providing a sample input (replace `5` with your desired number):<\/p>\n<pre lang=\"bash\">cargo run --bin default_clap -- --number 5\r\n<\/pre>\n<p>3. After executing the command, you should see the output displaying the number, square, and cube of the provided input.<\/p>\n<p>Example Output:<\/p>\n<pre lang=\"bash\">Number: 5\r\nSquare of number: 25\r\nCube of number: 125\r\n<\/pre>\n<figure id=\"attachment_21520\" aria-describedby=\"caption-attachment-21520\" style=\"width: 899px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2024\/02\/output-onlinegiftools.gif\" data-rel=\"lightbox-image-0\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2024\/02\/output-onlinegiftools.gif\" alt=\"Run default Clap program\" width=\"899\" height=\"535\" class=\"size-full wp-image-21520\" \/><\/a><figcaption id=\"caption-attachment-21520\" class=\"wp-caption-text\">Running your first Clap program<\/figcaption><\/figure>\n<p>4. To access help information about your Clap program and its available options, use the following command:<\/p>\n<pre lang=\"bash\">cargo run --bin default_clap -- -h\r\n<\/pre>\n<p>This command triggers Clap to display information about the available command-line options, their descriptions, and any other relevant details you&#8217;ve configured in your Clap program.<\/p>\n<p>Congratulations! You&#8217;ve successfully run your first Clap program!<\/p>\n<h4>The builder pattern<\/h4>\n<p>We just saw the simplest way to use Clap in the above example, next lets take a look at the Builder Pattern. For those wondering, Builder Pattern is another way to build your command line application using Clap which allows more advanced configuration options. It is useful when you need fine-grained control of your CLI.<br \/>\n1. To get started with builder pattern, we need to import the basics ie: <code>Command<\/code> and <code>Arg<\/code> structs from the Clap crate<\/p>\n<pre lang=\"rust\">use clap::{Command, Arg};\r\n<\/pre>\n<p><code>Command<\/code> is used for building command-line interfaces (CLIs). It defines the overall configuration and behavior of the CLI application while <code>Args<\/code> is used for defining individual command-line arguments.<br \/>\n2. Now, let&#8217;s look at a sample code snippet that uses the &#8216;Build Pattern&#8217; approach to create a new CLI application<\/p>\n<pre lang=\"rust\">let app = Command::new(\"Builder pattern program\")\r\n    .author(\"Me, me@gmail.com\")\r\n    .version(\"1.0\")\r\n    .about(\"Example to demonstrate builder pattern\")\r\n    .arg(\r\n        Arg::new(\"number\")\r\n    )\r\n    .get_matches();\r\n<\/pre>\n<p>The above code sets up a CLI application named &#8220;Builder pattern program&#8221; with author, version, and description information. It also defines a command-line argument named &#8220;number&#8221;. The get_matches() method is then called to parse and retrieve the matched values from the command line.<\/p>\n<h4>Argument Grouping<\/h4>\n<p>In more complex command-line applications, you might want to organize related arguments into groups. Clap provides the <code>ArgGroup<\/code> struct to facilitate this grouping. This feature becomes handy when you want to ensure that certain arguments are used together or mutually exclusive.<\/p>\n<p>1. Begin by importing the necessary module:<\/p>\n<pre lang=\"rust\">use clap::ArgGroup;\r\n<\/pre>\n<p>2. Define Argument Groups:<br \/>\nLet&#8217;s say you have two optional arguments, <code>--input<\/code> and <code>--output<\/code>, and you want to ensure that the user strictly provides only one of those arguments . You can create an argument group for this purpose in the following way.<\/p>\n<pre lang=\"rust\">let app = Command::new(\"ArgGroup Demo\")\r\n    .arg(Arg::new(\"input\"))\r\n    .arg(Arg::new(\"output\"))\r\n    .group(\r\n        ArgGroup::new(\"IO\")\r\n            .args(&amp;[\"Input\", \"Output\"])\r\n            .required(true),\r\n    );\r\n\r\n<\/pre>\n<p>In this example, the <code>ArgGroup::new(\"IO\")<\/code> creates a new group named &#8220;IO&#8221;. The <code>args(&amp;[\"input\", \"output\"])<\/code> method specifies which arguments belong to this group. Finally, <code>.required(true)<\/code> indicates that the user must provide either <code>--input<\/code> or <code>--output<\/code> but not both.<\/p>\n<p>3. Now, let&#8217;s say we have the same optional arguments, <code>--input<\/code> and <code>--output<\/code>, but you want to ensure that the user provides both of those arguments. You can create an argument group for this as follows.<\/p>\n<pre lang=\"rust\">let app = Command::new(\"ArgGroup Demo\")\r\n    .arg(Arg::new(\"input\"))\r\n    .arg(Arg::new(\"output\"))\r\n    .group(\r\n        ArgGroup::new(\"IO\")\r\n            .args(&amp;[\"Input\", \"Output\"])\r\n            .requires_all(true),\r\n    );\r\n<\/pre>\n<p>Here, same as in the previous snippet, <code>ArgGroup::new(\"IO\")<\/code> creates a new group named &#8220;IO.&#8221; The <code>args(&amp;[\"input\", \"output\"])<\/code> method specifies which arguments belong to this group. But, we use <code>.requires_all(true)<\/code> in this case to indicate that the user must provide both <code>--input<\/code> and <code>--output<\/code> arguments.<\/p>\n<p>Similarly, <code>ArgGroup<\/code> can be implemented for various other scenarios as well, for further details click <a href=\"https:\/\/cseweb.ucsd.edu\/classes\/sp22\/cse223B-a\/tribbler\/clap\/struct.ArgGroup.html\" target=\"_blank\" rel=\"noopener\">here<\/a><\/p>\n<h4>A complete example using Builder pattern<\/h4>\n<p>Now, let&#8217;s explore a complete example that demonstrates the builder pattern that also includes the grouping of command-line arguments.<\/p>\n<p>1. In this example, we will use the builder pattern in Clap to create a CLI application that calculates the square or cube of a number based on the chosen operation. We will also be using argument grouping to ensure that the user provides either &#8220;square&#8221; or &#8220;cube&#8221; but not both.<\/p>\n<p>2. Let&#8217;s start off by importing the dependencies<\/p>\n<pre lang=\"rust\">\/\/ Import necessary modules from the Clap crate\r\nuse clap::{Command, Arg, ArgGroup};\r\n<\/pre>\n<p>Here, we import the <code>Command<\/code>, <code>Arg<\/code>, and <code>ArgGroup<\/code> structs from the Clap crate. These will be used for building our command-line interface.<\/p>\n<p>3. Next, let&#8217;s build our CLI Configuration using Builder Pattern<\/p>\n<pre lang=\"rust\">\/\/ Build the CLI by defining the configuration using the builder pattern\r\nlet cmd = Command::new(\"NumberCalculator\")\r\n    .version(\"1.0\")\r\n    .about(\"Calculates square or cube of a number based on choice of operation\")\r\n    .arg(\r\n        Arg::new(\"number\")\r\n            .short('n')\r\n            .long(\"number\")\r\n            .num_args(1)\r\n            .value_parser(clap::value_parser!(i32))\r\n            .required(true)\r\n    )\r\n    .arg(\r\n        Arg::new(\"square\")\r\n            .short('s')\r\n            .long(\"square\")\r\n            .num_args(0)\r\n    )\r\n    .arg(\r\n        Arg::new(\"cube\")\r\n            .short('c')\r\n            .long(\"cube\")\r\n            .num_args(0)\r\n    )\r\n    .group(\r\n        ArgGroup::new(\"operation\")\r\n            .args([\"square\", \"cube\"])\r\n            .required(true)\r\n    );\r\n<\/pre>\n<p>Here, we use the <code>Command::new<\/code> method to initiate the CLI configuration. Then, we chain various methods like <code>version<\/code>, <code>about<\/code>, <code>arg<\/code>, and <code>group<\/code> to define the application&#8217;s behavior. We specify the number argument as required and the square and cube arguments as optional. The <code>ArgGroup::new<\/code> method is used to group the square and cube arguments, ensuring that only one of them can be provided.<\/p>\n<p>4. Now let us define the code to parse the runtime arguments.<\/p>\n<pre lang=\"rust\">    \/\/ Runtime argument parsing\r\n    let matches = cmd.get_matches();\r\n    let number_passed = matches.get_one(\"number\");\r\n    let number = match number_passed {\r\n        Some(number_passed) =&gt; number_passed,\r\n        None =&gt; &amp;0,\r\n    };\r\n<\/pre>\n<p>During runtime, we use <code>cmd.get_matches()<\/code> to parse the command-line arguments. We then retrieve the provided number using <code>matches.get_one(\"number\");<\/code>. The obtained value is then used in the subsequent code. If no value is provided for &#8220;number&#8221; ,it defaults to 0.<\/p>\n<p>5. Finally, we can perform the necessary calculations on the number based on the input provided.<\/p>\n<pre lang=\"rust\">    if let Some(true) = matches.get_one(\"cube\") {\r\n        println!(\"Cube of {} is: {}\", number, number * number * number);\r\n    } else if let Some(true) = matches.get_one(\"square\") {\r\n        println!(\"Square of {} is: {}\", number, number * number);\r\n    }\r\n<\/pre>\n<p>Here, <code>if let Some(true) = matches.get_one(\"cube\")<\/code> checks if the &#8220;cube&#8221; argument was present in the command line. If true, it calculates and prints the cube of the provided number.<br \/>\nSimilarly, <code>if let Some(true) = matches.get_one(\"square\")<\/code> checks if the &#8220;square&#8221; argument was present, and if true, it calculates and prints the square of the provided number.<\/p>\n<p>6. Putting it All Together<\/p>\n<pre lang=\"rust\">\/*\r\n    A CLI application showing\r\n        - grouping of command-line arguments\r\n*\/\r\nuse clap::{Command, Arg, ArgGroup};\r\n\r\nfn main() {\r\n    \/\/ Build the CLI by defining the configuration using builder pattern\r\n    let cmd = Command::new(\"NumberCalculator\")\r\n        .version(\"1.0\")\r\n        .about(\"Calculates square or cube of a number based on choice of operation\")\r\n        .arg(\r\n            Arg::new(\"number\")\r\n                .short('n')\r\n                .long(\"number\")\r\n                .num_args(1)\r\n                .value_parser(clap::value_parser!(i32))\r\n                .required(true)\r\n        )\r\n        .arg(\r\n            Arg::new(\"square\")\r\n                .short('s')\r\n                .long(\"square\")\r\n                .num_args(0)\r\n        )\r\n        .arg(\r\n            Arg::new(\"cube\")\r\n                .short('c')\r\n                .long(\"cube\")\r\n                .num_args(0)\r\n        )\r\n        .group(\r\n            ArgGroup::new(\"operation\")\r\n                .args([\"square\", \"cube\"])\r\n                .required(true)\r\n        );\r\n\r\n    \/\/ Runtime argument parsing\r\n    let matches = cmd.get_matches();\r\n    let number_passed = matches.get_one(\"number\");\r\n    let number = match number_passed {\r\n        Some(number_passed) =&gt; number_passed,\r\n        None =&gt; &amp;0,\r\n    };\r\n    if let Some(true) = matches.get_one(\"cube\") {\r\n        println!(\"Cube of {} is: {}\", number, number * number * number);\r\n    } else if let Some(true) = matches.get_one(\"square\") {\r\n        println!(\"Square of {} is: {}\", number, number * number);\r\n    }\r\n}\r\n<\/pre>\n<p>Example Output:<\/p>\n<pre lang=\"bash\">Number: 5\r\nOperation: Square\r\nSquare of number: 25\r\n<\/pre>\n<pre lang=\"bash\">Number: 5\r\nOperation: Cube\r\nCube of number: 125\r\n<\/pre>\n<figure id=\"attachment_21521\" aria-describedby=\"caption-attachment-21521\" style=\"width: 899px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2024\/02\/output-onlinegiftools-1.gif\" data-rel=\"lightbox-image-1\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2024\/02\/output-onlinegiftools-1.gif\" alt=\"Argument grouping and builder pattern program execution\" width=\"899\" height=\"535\" class=\"size-full wp-image-21521\" \/><\/a><figcaption id=\"caption-attachment-21521\" class=\"wp-caption-text\">Executing the  argument grouping program<\/figcaption><\/figure>\n<h4>Final thoughts<\/h4>\n<p>In conclusion, Clap proves to be a powerful and user-friendly tool for handling command line arguments. In this post, we covered integration of Clap into your project, building basic programs with both derive and the builder patterns, and explored features like argument grouping. Stay tuned for upcoming <a href=\"https:\/\/qxf2.com\/blog\/rust-clap-journey-a-little-further\/\" rel=\"noopener\" target=\"_blank\">blog<\/a> where we&#8217;ll dive deeper into Clap, exploring more of its feature like optional arguments, Boolean options, subcommands, and many more. Happy Coding!<\/p>\n<h4>Hire technical testers from Qxf2<\/h4>\n<p>Testers from Qxf2 continually learn and evolve. We have excellent testing fundamentals and constantly update our technical toolbelt. Engineering teams love working with us because we understand the problems they face and are in a position to compliment their technical abilities. If you are having a hard time hiring technical testers, <a href=\"https:\/\/qxf2.com\/contact?utm_source=Clap_in_Rust&amp;utm_medium=click&amp;utm_campaign=From%20blog\">get in touch with Qxf2<\/a>.<\/p>\n<hr \/>\n","protected":false},"excerpt":{"rendered":"<p>At Qxf2, our ongoing efforts involve delving into popular Rust crates and crafting tutorials to facilitate seamless adoption and utilization of these crates. As part of this undertaking, we turned our attention to the Clap crate, recognizing its significance as a valuable library for parsing command line arguments in Rust. This blog post aims to provide you with a comprehensive [&hellip;]<\/p>\n","protected":false},"author":29,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[401,402],"tags":[],"class_list":["post-20834","post","type-post","status-publish","format-standard","hentry","category-clap","category-rust-cli"],"_links":{"self":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/20834","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/users\/29"}],"replies":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/comments?post=20834"}],"version-history":[{"count":56,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/20834\/revisions"}],"predecessor-version":[{"id":21622,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/20834\/revisions\/21622"}],"wp:attachment":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/media?parent=20834"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/categories?post=20834"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/tags?post=20834"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}