# Building a CLI Tool in Rust

A quick guide to building a fast, ergonomic command-line tool using Rust and `clap`.

## Setup

Create a new project:

```bash
cargo new greet-cli
cd greet-cli
```

Add dependencies to `Cargo.toml`:

```toml
[dependencies]
clap = { version = "4", features = ["derive"] }
anyhow = "1"
```

## Defining the CLI

Use `clap`'s derive macros to define your arguments:

```rust
use clap::Parser;

#[derive(Parser)]
#[command(name = "greet", about = "A friendly greeter")]
struct Args {
    /// Name of the person to greet
    name: String,

    /// Number of times to greet
    #[arg(short, long, default_value_t = 1)]
    count: u8,

    /// Use uppercase
    #[arg(short, long)]
    uppercase: bool,
}
```

## The main function

```rust
use anyhow::Result;

fn main() -> Result<()> {
    let args = Args::parse();

    for _ in 0..args.count {
        let greeting = format!("Hello, {}!", args.name);
        if args.uppercase {
            println!("{}", greeting.to_uppercase());
        } else {
            println!("{greeting}");
        }
    }

    Ok(())
}
```

## Usage

```bash
$ cargo run -- world
Hello, world!

$ cargo run -- --count 3 --uppercase Rust
HELLO, RUST!
HELLO, RUST!
HELLO, RUST!
```

## Error handling

`anyhow` gives you ergonomic error handling. If you read a file:

```rust
use std::fs;

fn read_config(path: &str) -> Result<String> {
    let content = fs::read_to_string(path)?;
    Ok(content)
}
```

The `?` operator propagates errors with full context. No unwrap, no panic.

## Testing

Add tests in the same file:

```rust
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn verify_cli() {
        use clap::CommandFactory;
        Args::command().debug_assert();
    }
}
```

Run them:

```bash
cargo test
```

## Distribution

Build a release binary:

```bash
cargo build --release
```

The binary is at `target/release/greet`. It's a single static file — no runtime, no dependencies. Copy it anywhere and it works.

---

That's it. A complete CLI in under 50 lines of Rust. Fast to compile, fast to run, and pleasant to maintain.
