# Quickstart

## A new project

```bash
cargo new greet
cd greet
mkdir -p src/cli tests
```

The example keeps the command-line declaration separate from the two command handlers:

```text
greet/
├── Cargo.toml
├── src/
│   ├── main.rs
│   └── cli/
│       ├── mod.rs
│       ├── hello.rs
│       └── completion.rs
└── tests/
    └── cli.rs
```

## `Cargo.toml`

```toml
[dependencies]
usage = { package = "usage-rs", version = "6", features = ["completions"] }

[dev-dependencies]
usage = { package = "usage-rs", version = "6", features = ["test"] }
```

## `src/cli/mod.rs`

```rust
mod completion;
mod hello;

use completion::Completion;
use hello::Hello;
use usage::{Cli, Subcommands};

/// Greets people, politely
#[derive(Cli)]
#[usage(bin = "greet", version = "0.1.0", completion)]
pub(crate) struct Greet {
    #[usage(subcommand)]
    pub(crate) command: Commands,
}

#[derive(Subcommands)]
#[usage(run)] // Generate the match from each variant to its `Run` implementation.
pub(crate) enum Commands {
    Hello(Hello),
    Completion(Completion),
}
```

Doc comments on these types become help text. `completion` adds the shell-script methods and the
hidden request that `parse()` handles when a completion script calls the binary.

## `src/cli/hello.rs`

```rust
use usage::{Args, Run};

/// Greet someone
#[derive(Args)]
pub(crate) struct Hello {
    /// Who to greet
    #[usage(env = "GREET_NAME", default = "world")]
    name: String,
}

impl Run for Hello {
    type Output = ();
    fn run(self) {
        println!("hello, {}", self.name);
    }
}
```

## `src/cli/completion.rs`

```rust
use usage::{Args, Run};

use super::Greet;

/// Print a completion script
#[derive(Args)]
pub(crate) struct Completion {
    /// Which shell to generate for
    #[usage(long, choices("bash", "zsh", "fish"))]
    shell: String,
}

impl Run for Completion {
    type Output = ();
    fn run(self) {
        let shell = match self.shell.as_str() {
            "bash" => usage::complete::Shell::Bash,
            "zsh" => usage::complete::Shell::Zsh,
            _ => usage::complete::Shell::Fish,
        };
        // Generate the script for the shell the user selected.
        print!("{}", Greet::completion_script(shell));
    }
}
```

## `src/main.rs`

```rust
mod cli;

use cli::Greet;
use usage::Run;

fn main() {
    // `parse()` handles help, version, errors, and completion requests.
    // `run()` is the match generated by `#[usage(run)]`.
    Greet::parse().command.run()
}
```

## Run it

```console
$ greet hello
hello, world

$ GREET_NAME=Jeff greet hello       # env fallback, declared on the field
hello, Jeff
```

Help comes from the types and their doc comments:

```console
$ greet --help
greet 0.1.0
Greets people, politely

Usage: greet <SUBCOMMAND>

Commands:
  completion <--shell <SHELL>>
    Print a completion script

  hello [NAME]
    Greet someone

  help
    Print this message or the help of the given subcommand(s)

Flags:
  -h, --help     Print help
  -V, --version  Print version
```

Errors are clap-shaped, exit status included:

```console
$ greet helo
error: unrecognized subcommand 'helo'

  tip: a similar subcommand exists: 'hello'

Usage: greet <SUBCOMMAND>

For more information, try '--help'.

$ echo $?
2
```

## Completions

`usage-rs` provides the same dynamic completion system that powers mise. The generated script is
specific to the user's shell. When they press Tab, it calls back into `greet`; `parse()` handles
that hidden request and returns candidates and descriptions for the command line being typed.

```console
$ greet completion --shell fish | head -1
# @generated by usage-argv for `greet __complete_word__ --shell fish`
```

Tab-completing `greet ` offers `hello` and `completion` with their descriptions; `--shell `
offers `bash`, `zsh`, and `fish`. `install_completion` writes the generated script where that
shell looks for it. See [Completions](/rust/completions) for custom completers, aliases, file
completion, and installation.

## Docs and manpages

The generated spec can be passed to [usage-cli](/cli/) for documentation, manpages, completion
scripts, and other formats:

```bash
greet __usage_spec__ > greet.usage.kdl
usage g markdown -f greet.usage.kdl --out-dir docs   # markdown docs
usage g manpage  -f greet.usage.kdl > greet.1        # man page
```

This is the spec for the example CLI:

```kdl
name greet
bin greet
version "0.1.0"
about "Greets people, politely"
subcommand_required #true
cmd hello help="Greet someone" {
    arg "[NAME]" help="Who to greet" env=GREET_NAME default=world
}
cmd completion help="Print a completion script" {
    flag --shell help="Which shell to generate for" required=#true {
        arg <SHELL> {
            choices bash zsh fish
        }
    }
}
```

## `tests/cli.rs`

An integration test runs the compiled binary and captures the output a user sees:

```rust
#[test]
fn hello_greets_by_name() {
    let output = usage::test::command!("greet", "hello", "Jeff").assert_success();

    assert_eq!(output.stdout_text(), "hello, Jeff\n");
}
```

`command!` also retains stderr and the exit status. See [Testing](/rust/testing) for
process-free parser assertions, help-page snapshots, and completion candidates.

## Where next

- [Args and flags](/rust/args-and-flags) for the full attribute vocabulary
- [Subcommands](/rust/subcommands) for nesting, `flatten`, and value enums
- [Dispatch](/rust/dispatch) for contexts (`RunWith`) and async commands
- [Migrating from clap](/rust/migrating-from-clap) if you have a CLI already
