Getting Started with Rust Tool Base¶
Rust Tool Base (RTB) provides a batteries-included scaffolding for building robust CLI applications in Rust.
Status: RTB is currently in a pre-0.1 scaffolding phase. Most crates are intentional stubs. This guide demonstrates how to set up the minimal scaffold using the current API.
Quick Start Example¶
A working end-to-end example lives at examples/minimal in the repository. You can run it directly from the source tree:
$ cargo run -p rtb-example-minimal -- version
$ cargo run -p rtb-example-minimal -- greet
$ cargo run -p rtb-example-minimal -- doctor
$ cargo run -p rtb-example-minimal -- --help
Anatomy of an RTB Tool¶
A minimal RTB-based tool requires three core parts:
1. A custom Command implementation.
2. A linkme registration that inserts the command into the framework's command slice.
3. An Application::builder() call in your main function.
Requirements¶
Downstream tools must declare the following direct dependencies in Cargo.toml:
* rtb
* tokio
* miette
* async-trait
* linkme (Must be a direct dependency because its #[distributed_slice] attribute expands to ::linkme::… paths).
Minimal Example Code¶
use async_trait::async_trait;
use linkme::distributed_slice;
use rtb::core::app::App;
use rtb::core::command::{BUILTIN_COMMANDS, Command, CommandSpec};
use rtb::prelude::*;
// 1. Implement the Command trait.
struct Greet;
#[async_trait]
impl Command for Greet {
fn spec(&self) -> &CommandSpec {
static SPEC: CommandSpec = CommandSpec {
name: "greet",
about: "Print a friendly greeting",
aliases: &["hi"],
feature: None,
};
&SPEC
}
async fn run(&self, app: App) -> miette::Result<()> {
println!("hello from {}", app.metadata.name);
Ok(())
}
}
// 2. Register into the framework's command slice at link time.
#[distributed_slice(BUILTIN_COMMANDS)]
fn register_greet() -> Box<dyn Command> { Box::new(Greet) }
// 3. Wire the Application.
#[tokio::main]
async fn main() -> miette::Result<()> {
rtb::cli::Application::builder()
.metadata(
ToolMetadata::builder()
.name("mytool")
.summary("my CLI tool")
.build(),
)
.version(VersionInfo::from_env())
.build()?
.run()
.await
}
What's Next?¶
Once your basic CLI scaffold is running, you can explore adding more complex capabilities: