Building a Rust Command-Line Utility - wc-rs
Delving into Rust’s capabilities, this post guides you through the process of
crafting a command-line utility, wc-rs
, mirroring the functionality of the
classic wc
tool with a modern twist.
Introduction
The motivation to build wc-rs
comes from John Crickett’s
build your own wc
tool coding challenge. Solving these challenges is a
great way of learning different concepts, in my opinion. So, here we are
starting with our first one.
The challenge is to build your own version of the Unix command line tool wc
.
The functional requirements for wc
are concisely described by it’s man page -
give it a go in your local terminal now:
|
|
The TL/DR version is: wc
– word, line, character, and byte count.
So, let’s get Rusty!!
Code Walkthrough
The wc-rs
program is designed to be familiar to those who have used the original
wc
command, but under the hood, it leverages Rust’s advanced features for
improved performance and reliability.
The complete code is available at gauravgahlot/getting-rustywc-rs.
Dependencies
|
|
We use the clap crate to simplify command-line argument parsing, making it effortless to define and handle the flags and options our program accepts.
The CLI Struct
|
|
Our CLI
struct provides the skeleton for the command-line interface of
wc-rs
. With clap, beyond just defining the struct, we annotate it with
information like the program’s name, version, and a brief description.
Flags and Options
Each field in the CLI
struct represents a command-line flag or option,
complete with descriptive comments that clap uses to generate help messages:
-c
for byte count-l
for line count-w
for word count-m
for character count
The files
field holds an optional list of files to process. If it’s empty,
wc-rs
reads from standard input.
The Output Struct
|
|
As we prepare to crunch numbers, we store our results in the Output
struct.
This is where the counts of bytes, lines, words, and characters will be
accumulated, along with an optional filename for display purposes.
The Main Event
The main
function is where we tie everything together. We parse the command-line
arguments, iterate over files (or standard input), and calculate the statistics.
We handle files and potential I/O errors gracefully, reflecting Rust’s commitment
to safe and explicit error management.
|
|
Processing the Input
The process_lines
function is at the heart of wc-rs
. It takes a
reader—anything that implements the BufRead
trait—and an Output
struct by
mutable reference, updating the counts as it iterates over the lines in the text.
|
|
We account for characters and bytes differently depending on whether we’re reading from a file or from standard input to ensure accuracy. Word counts are obtained by splitting lines on spaces, highlighting Rust’s iterator and collection capabilities.
Showing the Numbers
Finally, print_output
is responsible for displaying the collected counts.
Following the flags provided, it either prints specific stats or defaults to
all counts if no flags are specified.
|
|
Getting wc-rs
Up and Running
To try out wc-rs
, you’ll compile and install it with cargo, Rust’s build
system and package manager. Once installed, running the program is just like
using the traditional wc.
Installation
You can install the CLI using the below command:
|
|
Help
By using the --help
option you can obtain the usage help for the CLI:
|
|
Examples
- Getting details of a single file:
|
|
- Getting details for multiple files:
|
|
- Getting details for data from standard input
|
|
- Display number of lines and characters only
|
|
Conclusion
wc-rs
might be a simple tool, but it embodies the elegance and robustness of
Rust for command-line applications. Through an exploration of this utility, we’ve
seen the power of meticulous error handling, the convenience of clap
for argument
parsing, and how straightforward it can be to work with files and strings in Rust.
Whether you’re an experienced developer or new to the command line, wc-rs
is a
testament to Rust’s capability to reinvent classic tools with a modern and
reliable twist.