Command Line Argument Parsing (
In this file, we define a
This allows us to pass command line arguments to our terminal user interface if we need to.
In addition to command line arguments, we typically want the version of the command line program to
show up on request. In the
clap command, we pass in an argument called
version() function (defined in
src/utils.rs) uses a environment variable called
RATATUI_ASYNC_TEMPLATE_GIT_INFO to get the version number with the git commit hash.
RATATUI_ASYNC_TEMPLATE_GIT_INFO is populated in
./build.rs when building with
of this line:
You can configure what the version string should look like by modifying the string template code in
XDG Base Directory Specification
Most command line tools have configuration files or data files that they need to store somewhere. To be a good citizen, you might want to consider following the XDG Base Directory Specification.
This template uses
ProjectDirs’s config and data local directories. You can
find more information about the exact location for your operating system here:
This template also prints out the location when you pass in the
--version command line argument.
There are situations where you or your users may want to override where the configuration and data
files should be located. This can be accomplished by using the environment variables
The functions that calculate the config and data directories are in
src/utils.rs. Feel free to
utils::get_data_dir() functions as you see fit.
utils::initialize_logging() function is defined in
src/utils.rs. The log level is decided by
RUST_LOG environment variable (default =
log::LevelFilter::Info). In addition, the location
of the log files are decided by the
RATATUI_ASYNC_TEMPLATE_DATA environment variable (default =
I tend to use
direnv for development purposes, and I have the following in my
This puts the log files in the
RATATUI_ASYNC_TEMPLATE_DATA folder, i.e.
.data folder in the
current directory, and sets the log level to
debug when I am prototyping and
RATATUI_ASYNC_TEMPLATE_CONFIG environment variable also allows me to have configuration
data that I can use for testing when development that doesn’t affect my local user configuration for
the same program.
Finally, let’s discuss the
initialize_panic_handler() function, which is also defined in
src/utils.rs, and is used to define a callback when the application panics. Your application may
panic for a number of reasons (e.g. when you call
.unwrap() on a
None). And when this happens,
you want to be a good citizen and:
- provide a useful stacktrace so that they can report errors back to you.
- not leave the users terminal state in a botched condition, resetting it back to the way it was.
In the screenshot below, I added a
None.unwrap() into a function that is called on a keypress, so
that you can see what a prettier backtrace looks like:
utils::initialize_panic_handler() also calls
Tui::new().exit() to reset the terminal state back
to the way it was before the user started the TUI program. We’ll learn more about the
Tui in the