Rust Fire
Image by T5, source: https://www.pixiv.net/artworks/104959772
Turn a Rust function or module into a command-line application with one attribute.
Installation
One function
/// Welcome a person.
$ app --name "John Smith" --excited
Welcome, John Smith!
#[fire::main] generates the program entry point, so no separate fn main() or
registration call is needed.
Help
-h and --help are generated automatically from the function signature and
documentation comments:
/// Start the HTTP server.
$ app --help
Start the HTTP server.
Usage: app --host <HOST> [--verbose]
Options:
--host <HOST> Address to listen on.
--verbose Enable verbose logging.
-h, --help Print help
For module applications, app --help lists the subcommands and
app <COMMAND> --help describes one subcommand.
Subcommands
Place #[fire::main] on an inline module to turn its pub functions into
subcommands. Private functions stay private, so a module can keep its helpers
next to its commands:
$ app hello --name John --times 2
Hello, John!
Hello, John!
$ app bye
Bye!
Rust snake_case function and parameter names are exposed as CLI kebab-case
names.
Parameters
The function signature defines the CLI:
| Rust type | CLI behavior |
|---|---|
T |
required option parsed with FromStr |
Option<T> |
optional option |
bool |
value-less flag, defaulting to false |
&str |
borrowed string option |
Both common option formats are accepted:
$ app --name John
$ app --name=John
An option may be given only once, and a value starting with - is never taken
from the next argument, so write it as --count=-1.
A command returns () or Result<_, E> where E: Display. Errors are printed
to stderr and the application exits with status 2.
The return value is dispatched through a trait rather than by matching on the
return type, so aliases such as anyhow::Result<()> work too. Any other return
type is a compile error.
Async
Pass tokio to the attribute to write async commands. Each async command
runs on a multi-threaded Tokio runtime, so add tokio with the
rt-multi-thread feature to your application:
/// Fetch a URL.
async
The same works on modules, and async and synchronous commands can be mixed in one module.
License
BSD-2-Clause.