Args - facet

# Args

`facet-args` turns any `Facet` struct into a command-line interface. Define your CLI with doc comments and attributes like `args::named`, `args::positional`, and `args::subcommand`. Get auto-generated help text, shell completions for bash/zsh/fish, and rich error diagnostics with typo suggestions.

## Successful Parsing

### Simple Arguments

Parse a struct with flags, options, and positional arguments.

Target Type

    /// A simple CLI tool for file processing.
    #[derive(Facet)]
    struct SimpleArgs {
        /// Enable verbose output
        #[facet(args::named, args::short)]
        verbose: bool,

        /// Number of parallel jobs to run
        #[facet(args::named, args::short)]
        jobs: Option<usize>,

        /// Input file to process
        #[facet(args::positional)]
        input: String,

        /// Output file (defaults to stdout)
        #[facet(args::positional)]
        output: Option<String>,
    }

#### Rust Input

    from_slice(&["-v", "-j", "4", "input.txt", "output.txt"])

#### Success

    SimpleArgs {
      verbose: true,
      jobs: Option::Some(4),
      input: "input.txt",
      output: Option::Some("output.txt"),
    }

### Attached Short Flag Value

Short flags can have their values attached directly without a space.

Target Type

    /// A simple CLI tool for file processing.
    #[derive(Facet)]
    struct SimpleArgs {
        /// Enable verbose output
        #[facet(args::named, args::short)]
        verbose: bool,

        /// Number of parallel jobs to run
        #[facet(args::named, args::short)]
        jobs: Option<usize>,

        /// Input file to process
        #[facet(args::positional)]
        input: String,

        /// Output file (defaults to stdout)
        #[facet(args::positional)]
        output: Option<String>,
    }

#### Rust Input

    from_slice(&["-j4", "input.txt"])

#### Success

    SimpleArgs {
      verbose: false,
      jobs: Option::Some(4),
      input: "input.txt",
      output: Option::None,
    }

### Boolean Flag with Explicit Value

Boolean flags can be explicitly set to true or false using `=`.

Target Type

    /// A simple CLI tool for file processing.
    #[derive(Facet)]
    struct SimpleArgs {
        /// Enable verbose output
        #[facet(args::named, args::short)]
        verbose: bool,

        /// Number of parallel jobs to run
        #[facet(args::named, args::short)]
        jobs: Option<usize>,

        /// Input file to process
        #[facet(args::positional)]
        input: String,

        /// Output file (defaults to stdout)
        #[facet(args::positional)]
        output: Option<String>,
    }

#### Rust Input

    from_slice(&["--verbose=true", "input.txt"])

#### Success

    SimpleArgs {
      verbose: true,
      jobs: Option::None,
      input: "input.txt",
      output: Option::None,
    }

### Short Flag Chaining

Multiple boolean short flags can be combined: `-sb` is equivalent to `-s -b`.

Target Type

    /// Git-like CLI with subcommands.
    #[derive(Facet)]
    struct GitLikeArgs {
        /// Show version information
        #[facet(args::named)]
        version: bool,

        /// Git command to run
        #[facet(args::subcommand)]
        command: GitCommand,
    }

    /// Available commands
    #[derive(Facet)]
    #[repr(u8)]
    enum GitCommand {
        /// Clone a repository into a new directory
        Clone {
            /// The repository URL to clone
            #[facet(args::positional)]
            url: String,

            /// Directory to clone into
            #[facet(args::positional)]
            directory: Option<String>,

            /// Clone only the specified branch
            #[facet(args::named, args::short)]
            branch: Option<String>,

            /// Create a shallow clone with limited history
            #[facet(args::named)]
            depth: Option<usize>,
        },

        /// Show the working tree status
        Status {
            /// Show short-format output
            #[facet(args::named, args::short)]
            short: bool,

            /// Show the branch even in short-format
            #[facet(args::named, args::short)]
            branch: bool,
        },

        /// Manage set of tracked repositories
        Remote {
            /// Remote action to perform
            #[facet(args::subcommand)]
            action: RemoteAction,
        },
    }

    /// Remote management commands
    #[derive(Facet)]
    #[repr(u8)]
    enum RemoteAction {
        /// Add a remote named <name> for the repository at <url>
        Add {
            /// Name of the remote
            #[facet(args::positional)]
            name: String,

            /// URL of the remote repository
            #[facet(args::positional)]
            url: String,
        },

        /// Remove the remote named <name>
        rm {
            /// Name of the remote to remove
            #[facet(args::positional)]
            name: String,
        },

        /// List all remotes
        ls {
            /// Show remote URLs after names
            #[facet(args::named, args::short)]
            verbose: bool,
        },
    }

#### Rust Input

    from_slice(&["status", "-sb"])

#### Success

    GitLikeArgs {
      version: false,
      command: GitCommand::Status {
        short: true,
        branch: true,
      },
    }

### Subcommands

Parse a CLI with subcommands, each with their own arguments.

Target Type

    /// Git-like CLI with subcommands.
    #[derive(Facet)]
    struct GitLikeArgs {
        /// Show version information
        #[facet(args::named)]
        version: bool,

        /// Git command to run
        #[facet(args::subcommand)]
        command: GitCommand,
    }

    /// Available commands
    #[derive(Facet)]
    #[repr(u8)]
    enum GitCommand {
        /// Clone a repository into a new directory
        Clone {
            /// The repository URL to clone
            #[facet(args::positional)]
            url: String,

            /// Directory to clone into
            #[facet(args::positional)]
            directory: Option<String>,

            /// Clone only the specified branch
            #[facet(args::named, args::short)]
            branch: Option<String>,

            /// Create a shallow clone with limited history
            #[facet(args::named)]
            depth: Option<usize>,
        },

        /// Show the working tree status
        Status {
            /// Show short-format output
            #[facet(args::named, args::short)]
            short: bool,

            /// Show the branch even in short-format
            #[facet(args::named, args::short)]
            branch: bool,
        },

        /// Manage set of tracked repositories
        Remote {
            /// Remote action to perform
            #[facet(args::subcommand)]
            action: RemoteAction,
        },
    }

    /// Remote management commands
    #[derive(Facet)]
    #[repr(u8)]
    enum RemoteAction {
        /// Add a remote named <name> for the repository at <url>
        Add {
            /// Name of the remote
            #[facet(args::positional)]
            name: String,

            /// URL of the remote repository
            #[facet(args::positional)]
            url: String,
        },

        /// Remove the remote named <name>
        rm {
            /// Name of the remote to remove
            #[facet(args::positional)]
            name: String,
        },

        /// List all remotes
        ls {
            /// Show remote URLs after names
            #[facet(args::named, args::short)]
            verbose: bool,
        },
    }

#### Rust Input

    from_slice(&["clone", "--branch", "main", "https://github.com/user/repo"])

#### Success

    GitLikeArgs {
      version: false,
      command: GitCommand::Clone {
        url: "https://github.com/user/repo",
        directory: Option::None,
        branch: Option::Some("main"),
        depth: Option::None,
      },
    }

### Nested Subcommands

Parse deeply nested subcommands like `git remote add`.

Target Type

    /// Git-like CLI with subcommands.
    #[derive(Facet)]
    struct GitLikeArgs {
        /// Show version information
        #[facet(args::named)]
        version: bool,

        /// Git command to run
        #[facet(args::subcommand)]
        command: GitCommand,
    }

    /// Available commands
    #[derive(Facet)]
    #[repr(u8)]
    enum GitCommand {
        /// Clone a repository into a new directory
        Clone {
            /// The repository URL to clone
            #[facet(args::positional)]
            url: String,

            /// Directory to clone into
            #[facet(args::positional)]
            directory: Option<String>,

            /// Clone only the specified branch
            #[facet(args::named, args::short)]
            branch: Option<String>,

            /// Create a shallow clone with limited history
            #[facet(args::named)]
            depth: Option<usize>,
        },

        /// Show the working tree status
        Status {
            /// Show short-format output
            #[facet(args::named, args::short)]
            short: bool,

            /// Show the branch even in short-format
            #[facet(args::named, args::short)]
            branch: bool,
        },

        /// Manage set of tracked repositories
        Remote {
            /// Remote action to perform
            #[facet(args::subcommand)]
            action: RemoteAction,
        },
    }

    /// Remote management commands
    #[derive(Facet)]
    #[repr(u8)]
    enum RemoteAction {
        /// Add a remote named <name> for the repository at <url>
        Add {
            /// Name of the remote
            #[facet(args::positional)]
            name: String,

            /// URL of the remote repository
            #[facet(args::positional)]
            url: String,
        },

        /// Remove the remote named <name>
        rm {
            /// Name of the remote to remove
            #[facet(args::positional)]
            name: String,
        },

        /// List all remotes
        ls {
            /// Show remote URLs after names
            #[facet(args::named, args::short)]
            verbose: bool,
        },
    }

#### Rust Input

    from_slice(&["remote", "add", "origin", "https://github.com/user/repo"])

#### Success

    GitLikeArgs {
      version: false,
      command: GitCommand::Remote {
        action: RemoteAction::Add {
          name: "origin",
          url: "https://github.com/user/repo",
        },
      },
    }

## Help Generation

### Simple Help

Auto-generated help text from struct definition and doc comments.

Target Type

    /// A simple CLI tool for file processing.
    #[derive(Facet)]
    struct SimpleArgs {
        /// Enable verbose output
        #[facet(args::named, args::short)]
        verbose: bool,

        /// Number of parallel jobs to run
        #[facet(args::named, args::short)]
        jobs: Option<usize>,

        /// Input file to process
        #[facet(args::positional)]
        input: String,

        /// Output file (defaults to stdout)
        #[facet(args::positional)]
        output: Option<String>,
    }

    mytool 1.0.0
    A simple CLI tool for file processing.
    USAGE:
        mytool [OPTIONS] <INPUT> [OUTPUT]
    ARGUMENTS:
            <INPUT>
                Input file to process
            <OUTPUT>
                Output file (defaults to stdout)
    OPTIONS:
        -v, --verbose
                Enable verbose output
        -j, --jobs <OPTION>
                Number of parallel jobs to run

### Automatic --help Detection

When `-h`, `--help`, `-help`, or `/?` is the first argument, help is automatically generated and returned.

Target Type

    /// A simple CLI tool for file processing.
    #[derive(Facet)]
    struct SimpleArgs {
        /// Enable verbose output
        #[facet(args::named, args::short)]
        verbose: bool,

        /// Number of parallel jobs to run
        #[facet(args::named, args::short)]
        jobs: Option<usize>,

        /// Input file to process
        #[facet(args::positional)]
        input: String,

        /// Output file (defaults to stdout)
        #[facet(args::positional)]
        output: Option<String>,
    }

#### Rust Input

    from_slice(&["--help"])

    target/debug/examples/args_showcase
    A simple CLI tool for file processing.
    USAGE:
        target/debug/examples/args_showcase [OPTIONS] <INPUT> [OUTPUT]
    ARGUMENTS:
            <INPUT>
                Input file to process
            <OUTPUT>
                Output file (defaults to stdout)
    OPTIONS:
        -v, --verbose
                Enable verbose output
        -j, --jobs <OPTION>
                Number of parallel jobs to run

### Help with Subcommands

Help text automatically lists available subcommands with descriptions.

Target Type

    /// Git-like CLI with subcommands.
    #[derive(Facet)]
    struct GitLikeArgs {
        /// Show version information
        #[facet(args::named)]
        version: bool,

        /// Git command to run
        #[facet(args::subcommand)]
        command: GitCommand,
    }

    /// Available commands
    #[derive(Facet)]
    #[repr(u8)]
    enum GitCommand {
        /// Clone a repository into a new directory
        Clone {
            /// The repository URL to clone
            #[facet(args::positional)]
            url: String,

            /// Directory to clone into
            #[facet(args::positional)]
            directory: Option<String>,

            /// Clone only the specified branch
            #[facet(args::named, args::short)]
            branch: Option<String>,

            /// Create a shallow clone with limited history
            #[facet(args::named)]
            depth: Option<usize>,
        },

        /// Show the working tree status
        Status {
            /// Show short-format output
            #[facet(args::named, args::short)]
            short: bool,

            /// Show the branch even in short-format
            #[facet(args::named, args::short)]
            branch: bool,
        },

        /// Manage set of tracked repositories
        Remote {
            /// Remote action to perform
            #[facet(args::subcommand)]
            action: RemoteAction,
        },
    }

    /// Remote management commands
    #[derive(Facet)]
    #[repr(u8)]
    enum RemoteAction {
        /// Add a remote named <name> for the repository at <url>
        Add {
            /// Name of the remote
            #[facet(args::positional)]
            name: String,

            /// URL of the remote repository
            #[facet(args::positional)]
            url: String,
        },

        /// Remove the remote named <name>
        rm {
            /// Name of the remote to remove
            #[facet(args::positional)]
            name: String,
        },

        /// List all remotes
        ls {
            /// Show remote URLs after names
            #[facet(args::named, args::short)]
            verbose: bool,
        },
    }

    git 2.40.0
    Git-like CLI with subcommands.
    USAGE:
        git [OPTIONS] <COMMAND>
    OPTIONS:
            --version
                Show version information
    COMMANDS:
        clone
                Clone a repository into a new directory
        status
                Show the working tree status
        remote
                Manage set of tracked repositories

## Shell Completions

### Bash Completions

Generated Bash completion script for tab-completion support.

Target Type

    /// A build tool configuration
    #[derive(Facet)]
    struct BuildArgs {
        /// Build in release mode with optimizations
        #[facet(args::named, args::short)]
        release: bool,

        /// Number of parallel jobs
        #[facet(args::named, args::short)]
        jobs: Option<usize>,

        /// Package to build
        #[facet(args::named, args::short)]
        package: Option<String>,

        /// Build all packages in the workspace
        #[facet(args::named)]
        workspace: bool,

        /// Space-separated list of features to enable
        #[facet(args::named, args::short)]
        features: Option<String>,

        /// Target triple to build for
        #[facet(args::named)]
        target: Option<String>,
    }

#### Output Output

    _cargo-build() {
        local cur prev words cword
        _init_completion || return

        local commands=""
        local flags=""

        flags="--release -r --jobs -j --package -p --workspace --features -F --target"

        case "$prev" in
            # Add cases for flags that take values
            *)
                ;;
        esac

        if [[ "$cur" == -* ]]; then
            COMPREPLY=($(compgen -W "$flags" -- "$cur"))
        elif [[ -n "$commands" ]]; then
            COMPREPLY=($(compgen -W "$commands" -- "$cur"))
        fi
    }

    complete -F _cargo-build cargo-build

### Zsh Completions

Generated Zsh completion script with argument descriptions.

Target Type

    /// A build tool configuration
    #[derive(Facet)]
    struct BuildArgs {
        /// Build in release mode with optimizations
        #[facet(args::named, args::short)]
        release: bool,

        /// Number of parallel jobs
        #[facet(args::named, args::short)]
        jobs: Option<usize>,

        /// Package to build
        #[facet(args::named, args::short)]
        package: Option<String>,

        /// Build all packages in the workspace
        #[facet(args::named)]
        workspace: bool,

        /// Space-separated list of features to enable
        #[facet(args::named, args::short)]
        features: Option<String>,

        /// Target triple to build for
        #[facet(args::named)]
        target: Option<String>,
    }

#### Output Output

    #compdef cargo-build

    _cargo-build() {
        local -a commands
        local -a options

        options=(
            '-r[Build in release mode with optimizations]'
            '--release[Build in release mode with optimizations]'
            '-j[Number of parallel jobs]'
            '--jobs[Number of parallel jobs]'
            '-p[Package to build]'
            '--package[Package to build]'
            '--workspace[Build all packages in the workspace]'
            '-F[Space-separated list of features to enable]'
            '--features[Space-separated list of features to enable]'
            '--target[Target triple to build for]'
        )

        _arguments $options
    }

    _cargo-build "$@"

### Fish Completions

Generated Fish shell completion script.

Target Type

    /// A build tool configuration
    #[derive(Facet)]
    struct BuildArgs {
        /// Build in release mode with optimizations
        #[facet(args::named, args::short)]
        release: bool,

        /// Number of parallel jobs
        #[facet(args::named, args::short)]
        jobs: Option<usize>,

        /// Package to build
        #[facet(args::named, args::short)]
        package: Option<String>,

        /// Build all packages in the workspace
        #[facet(args::named)]
        workspace: bool,

        /// Space-separated list of features to enable
        #[facet(args::named, args::short)]
        features: Option<String>,

        /// Target triple to build for
        #[facet(args::named)]
        target: Option<String>,
    }

#### Output Output

    # Fish completion for cargo-build

    complete -c cargo-build -s r -l release -d 'Build in release mode with optimizations'
    complete -c cargo-build -s j -l jobs -d 'Number of parallel jobs'
    complete -c cargo-build -s p -l package -d 'Package to build'
    complete -c cargo-build -l workspace -d 'Build all packages in the workspace'
    complete -c cargo-build -s F -l features -d 'Space-separated list of features to enable'
    complete -c cargo-build -l target -d 'Target triple to build for'

## Error Diagnostics

### Unknown Flag

Error when an unrecognized flag is provided.

Target Type

    /// A simple CLI tool for file processing.
    #[derive(Facet)]
    struct SimpleArgs {
        /// Enable verbose output
        #[facet(args::named, args::short)]
        verbose: bool,

        /// Number of parallel jobs to run
        #[facet(args::named, args::short)]
        jobs: Option<usize>,

        /// Input file to process
        #[facet(args::positional)]
        input: String,

        /// Output file (defaults to stdout)
        #[facet(args::positional)]
        output: Option<String>,
    }

#### Rust Input

    from_slice(&["--verbos", "input.txt"])

    [args::unknown_long_flag] Error: unknown flag `--verbos`
       ╭─[ <unknown>:1:1 ]
       │
     1 │ --verbos input.txt
       │ ────┬───
       │     ╰───── unknown flag `--verbos`
       │
       │ Help: did you mean `--verbose`?
    ───╯

### Unknown Flag with Suggestion

When the flag name is close to a valid one, a suggestion is offered.

Target Type

    /// A build tool configuration
    #[derive(Facet)]
    struct BuildArgs {
        /// Build in release mode with optimizations
        #[facet(args::named, args::short)]
        release: bool,

        /// Number of parallel jobs
        #[facet(args::named, args::short)]
        jobs: Option<usize>,

        /// Package to build
        #[facet(args::named, args::short)]
        package: Option<String>,

        /// Build all packages in the workspace
        #[facet(args::named)]
        workspace: bool,

        /// Space-separated list of features to enable
        #[facet(args::named, args::short)]
        features: Option<String>,

        /// Target triple to build for
        #[facet(args::named)]
        target: Option<String>,
    }

#### Rust Input

    from_slice(&["--releas"])

    [args::unknown_long_flag] Error: unknown flag `--releas`
       ╭─[ <unknown>:1:1 ]
       │
     1 │ --releas
       │ ────┬───
       │     ╰───── unknown flag `--releas`
       │
       │ Help: did you mean `--release`?
    ───╯

### Invalid Short Flag in Chain

When chaining short flags, an unknown flag is reported with available options.

Target Type

    /// A simple CLI tool for file processing.
    #[derive(Facet)]
    struct SimpleArgs {
        /// Enable verbose output
        #[facet(args::named, args::short)]
        verbose: bool,

        /// Number of parallel jobs to run
        #[facet(args::named, args::short)]
        jobs: Option<usize>,

        /// Input file to process
        #[facet(args::positional)]
        input: String,

        /// Output file (defaults to stdout)
        #[facet(args::positional)]
        output: Option<String>,
    }

#### Rust Input

    from_slice(&["-vxyz", "input.txt"])

    [args::unknown_short_flag] Error: unknown flag `-x`
       ╭─[ <unknown>:1:3 ]
       │
     1 │ -vxyz input.txt
       │   ┬
       │   ╰── unknown flag `-x`
       │
       │ Help: available options:
       │         -v, --verbose  Enable verbose output
       │         -j, --jobs     Number of parallel jobs to run
       │             <input>    Input file to process
       │             <output>   Output file (defaults to stdout)
    ───╯

### Triple Dash Flag

Flags with too many dashes are rejected.

Target Type

    /// A simple CLI tool for file processing.
    #[derive(Facet)]
    struct SimpleArgs {
        /// Enable verbose output
        #[facet(args::named, args::short)]
        verbose: bool,

        /// Number of parallel jobs to run
        #[facet(args::named, args::short)]
        jobs: Option<usize>,

        /// Input file to process
        #[facet(args::positional)]
        input: String,

        /// Output file (defaults to stdout)
        #[facet(args::positional)]
        output: Option<String>,
    }

#### Rust Input

    from_slice(&["---verbose", "input.txt"])

    [args::unknown_long_flag] Error: unknown flag `---verbose`
       ╭─[ <unknown>:1:1 ]
       │
     1 │ ---verbose input.txt
       │ ─────┬────
       │      ╰────── unknown flag `---verbose`
       │
       │ Help: available options:
       │         -v, --verbose  Enable verbose output
       │         -j, --jobs     Number of parallel jobs to run
       │             <input>    Input file to process
       │             <output>   Output file (defaults to stdout)
    ───╯

### Single Dash with Long Name

Long flag names require double dashes.

Target Type

    /// A simple CLI tool for file processing.
    #[derive(Facet)]
    struct SimpleArgs {
        /// Enable verbose output
        #[facet(args::named, args::short)]
        verbose: bool,

        /// Number of parallel jobs to run
        #[facet(args::named, args::short)]
        jobs: Option<usize>,

        /// Input file to process
        #[facet(args::positional)]
        input: String,

        /// Output file (defaults to stdout)
        #[facet(args::positional)]
        output: Option<String>,
    }

#### Rust Input

    from_slice(&["-verbose", "input.txt"])

    [args::unknown_short_flag] Error: unknown flag `-e`
       ╭─[ <unknown>:1:3 ]
       │
     1 │ -verbose input.txt
       │   ┬
       │   ╰── unknown flag `-e`
       │
       │ Help: available options:
       │         -v, --verbose  Enable verbose output
       │         -j, --jobs     Number of parallel jobs to run
       │             <input>    Input file to process
       │             <output>   Output file (defaults to stdout)
    ───╯

### Missing Value

Error when a flag that requires a value doesn't get one.

Target Type

    /// A simple CLI tool for file processing.
    #[derive(Facet)]
    struct SimpleArgs {
        /// Enable verbose output
        #[facet(args::named, args::short)]
        verbose: bool,

        /// Number of parallel jobs to run
        #[facet(args::named, args::short)]
        jobs: Option<usize>,

        /// Input file to process
        #[facet(args::positional)]
        input: String,

        /// Output file (defaults to stdout)
        #[facet(args::positional)]
        output: Option<String>,
    }

#### Rust Input

    from_slice(&["-j"])

    [args::expected_value] Error: expected `usize` value
       ╭─[ <unknown>:1:1 ]
       │
     1 │ -j
       │ ─┬
       │  ╰── expected `usize` value
       │
       │ Help: provide a value after the flag
    ───╯

### Missing Required Argument

Error when a required positional argument is not provided.

Target Type

    /// A simple CLI tool for file processing.
    #[derive(Facet)]
    struct SimpleArgs {
        /// Enable verbose output
        #[facet(args::named, args::short)]
        verbose: bool,

        /// Number of parallel jobs to run
        #[facet(args::named, args::short)]
        jobs: Option<usize>,

        /// Input file to process
        #[facet(args::positional)]
        input: String,

        /// Output file (defaults to stdout)
        #[facet(args::positional)]
        output: Option<String>,
    }

#### Rust Input

    from_slice(&["-v"])

    [args::missing_argument] Error: missing required argument `<input>` (Input file to process)
       ╭─[ <unknown>:1:4 ]
       │
     1 │ -v
       │    │
       │    ╰─ missing required argument `<input>` (Input file to process)
       │
       │ Help: provide a value for `<input>`
    ───╯

### Unexpected Positional Argument

Error when a positional argument is provided but not expected.

Target Type

    /// A build tool configuration
    #[derive(Facet)]
    struct BuildArgs {
        /// Build in release mode with optimizations
        #[facet(args::named, args::short)]
        release: bool,

        /// Number of parallel jobs
        #[facet(args::named, args::short)]
        jobs: Option<usize>,

        /// Package to build
        #[facet(args::named, args::short)]
        package: Option<String>,

        /// Build all packages in the workspace
        #[facet(args::named)]
        workspace: bool,

        /// Space-separated list of features to enable
        #[facet(args::named, args::short)]
        features: Option<String>,

        /// Target triple to build for
        #[facet(args::named)]
        target: Option<String>,
    }

#### Rust Input

    from_slice(&["extra", "--release"])

    [args::unexpected_positional] Error: unexpected positional argument
       ╭─[ <unknown>:1:1 ]
       │
     1 │ extra --release
       │ ──┬──
       │   ╰──── unexpected positional argument
       │
       │ Help: available options:
       │         -r, --release    Build in release mode with optimizations
       │         -j, --jobs       Number of parallel jobs
       │         -p, --package    Package to build
       │             --workspace  Build all packages in the workspace
       │         -F, --features   Space-separated list of features to enable
       │             --target     Target triple to build for
    ───╯

### Unknown Subcommand

Error when an unrecognized subcommand is provided, with available options listed.

Target Type

    /// Git-like CLI with subcommands.
    #[derive(Facet)]
    struct GitLikeArgs {
        /// Show version information
        #[facet(args::named)]
        version: bool,

        /// Git command to run
        #[facet(args::subcommand)]
        command: GitCommand,
    }

    /// Available commands
    #[derive(Facet)]
    #[repr(u8)]
    enum GitCommand {
        /// Clone a repository into a new directory
        Clone {
            /// The repository URL to clone
            #[facet(args::positional)]
            url: String,

            /// Directory to clone into
            #[facet(args::positional)]
            directory: Option<String>,

            /// Clone only the specified branch
            #[facet(args::named, args::short)]
            branch: Option<String>,

            /// Create a shallow clone with limited history
            #[facet(args::named)]
            depth: Option<usize>,
        },

        /// Show the working tree status
        Status {
            /// Show short-format output
            #[facet(args::named, args::short)]
            short: bool,

            /// Show the branch even in short-format
            #[facet(args::named, args::short)]
            branch: bool,
        },

        /// Manage set of tracked repositories
        Remote {
            /// Remote action to perform
            #[facet(args::subcommand)]
            action: RemoteAction,
        },
    }

    /// Remote management commands
    #[derive(Facet)]
    #[repr(u8)]
    enum RemoteAction {
        /// Add a remote named <name> for the repository at <url>
        Add {
            /// Name of the remote
            #[facet(args::positional)]
            name: String,

            /// URL of the remote repository
            #[facet(args::positional)]
            url: String,
        },

        /// Remove the remote named <name>
        rm {
            /// Name of the remote to remove
            #[facet(args::positional)]
            name: String,
        },

        /// List all remotes
        ls {
            /// Show remote URLs after names
            #[facet(args::named, args::short)]
            verbose: bool,
        },
    }

#### Rust Input

    from_slice(&["clon", "https://example.com"])

    [args::unknown_subcommand] Error: unknown subcommand `clon`
       ╭─[ <unknown>:1:1 ]
       │
     1 │ clon https://example.com
       │ ──┬─
       │   ╰─── unknown subcommand `clon`
       │
       │ Help: did you mean `clone`?
    ───╯

### Missing Subcommand

Error when a required subcommand is not provided.

Target Type

    /// Git-like CLI with subcommands.
    #[derive(Facet)]
    struct GitLikeArgs {
        /// Show version information
        #[facet(args::named)]
        version: bool,

        /// Git command to run
        #[facet(args::subcommand)]
        command: GitCommand,
    }

    /// Available commands
    #[derive(Facet)]
    #[repr(u8)]
    enum GitCommand {
        /// Clone a repository into a new directory
        Clone {
            /// The repository URL to clone
            #[facet(args::positional)]
            url: String,

            /// Directory to clone into
            #[facet(args::positional)]
            directory: Option<String>,

            /// Clone only the specified branch
            #[facet(args::named, args::short)]
            branch: Option<String>,

            /// Create a shallow clone with limited history
            #[facet(args::named)]
            depth: Option<usize>,
        },

        /// Show the working tree status
        Status {
            /// Show short-format output
            #[facet(args::named, args::short)]
            short: bool,

            /// Show the branch even in short-format
            #[facet(args::named, args::short)]
            branch: bool,
        },

        /// Manage set of tracked repositories
        Remote {
            /// Remote action to perform
            #[facet(args::subcommand)]
            action: RemoteAction,
        },
    }

    /// Remote management commands
    #[derive(Facet)]
    #[repr(u8)]
    enum RemoteAction {
        /// Add a remote named <name> for the repository at <url>
        Add {
            /// Name of the remote
            #[facet(args::positional)]
            name: String,

            /// URL of the remote repository
            #[facet(args::positional)]
            url: String,
        },

        /// Remove the remote named <name>
        rm {
            /// Name of the remote to remove
            #[facet(args::positional)]
            name: String,
        },

        /// List all remotes
        ls {
            /// Show remote URLs after names
            #[facet(args::named, args::short)]
            verbose: bool,
        },
    }

#### Rust Input

    from_slice(&["--version"])

    [args::missing_subcommand] Error: expected a subcommand
       ╭─[ <unknown>:1:11 ]
       │
     1 │ --version
       │           │
       │           ╰─ expected a subcommand
       │
       │ Help: available subcommands:
       │         clone   Clone a repository into a new directory
       │         status  Show the working tree status
       │         remote  Manage set of tracked repositories
    ───╯

### Missing Nested Subcommand Argument

Error when a required argument in a nested subcommand is missing.

Target Type

    /// Git-like CLI with subcommands.
    #[derive(Facet)]
    struct GitLikeArgs {
        /// Show version information
        #[facet(args::named)]
        version: bool,

        /// Git command to run
        #[facet(args::subcommand)]
        command: GitCommand,
    }

    /// Available commands
    #[derive(Facet)]
    #[repr(u8)]
    enum GitCommand {
        /// Clone a repository into a new directory
        Clone {
            /// The repository URL to clone
            #[facet(args::positional)]
            url: String,

            /// Directory to clone into
            #[facet(args::positional)]
            directory: Option<String>,

            /// Clone only the specified branch
            #[facet(args::named, args::short)]
            branch: Option<String>,

            /// Create a shallow clone with limited history
            #[facet(args::named)]
            depth: Option<usize>,
        },

        /// Show the working tree status
        Status {
            /// Show short-format output
            #[facet(args::named, args::short)]
            short: bool,

            /// Show the branch even in short-format
            #[facet(args::named, args::short)]
            branch: bool,
        },

        /// Manage set of tracked repositories
        Remote {
            /// Remote action to perform
            #[facet(args::subcommand)]
            action: RemoteAction,
        },
    }

    /// Remote management commands
    #[derive(Facet)]
    #[repr(u8)]
    enum RemoteAction {
        /// Add a remote named <name> for the repository at <url>
        Add {
            /// Name of the remote
            #[facet(args::positional)]
            name: String,

            /// URL of the remote repository
            #[facet(args::positional)]
            url: String,
        },

        /// Remove the remote named <name>
        rm {
            /// Name of the remote to remove
            #[facet(args::positional)]
            name: String,
        },

        /// List all remotes
        ls {
            /// Show remote URLs after names
            #[facet(args::named, args::short)]
            verbose: bool,
        },
    }

#### Rust Input

    from_slice(&["remote", "add", "origin"])

    [args::missing_argument] Error: missing required argument `<url>` (URL of the remote repository)
       ╭─[ <unknown>:1:19 ]
       │
     1 │ remote add origin
       │                   │
       │                   ╰─ missing required argument `<url>` (URL of the remote repository)
       │
       │ Help: provide a value for `<url>`
    ───╯

### Invalid Value Type

Error when a value cannot be parsed as the expected type.

Target Type

    /// A simple CLI tool for file processing.
    #[derive(Facet)]
    struct SimpleArgs {
        /// Enable verbose output
        #[facet(args::named, args::short)]
        verbose: bool,

        /// Number of parallel jobs to run
        #[facet(args::named, args::short)]
        jobs: Option<usize>,

        /// Input file to process
        #[facet(args::positional)]
        input: String,

        /// Output file (defaults to stdout)
        #[facet(args::positional)]
        output: Option<String>,
    }

#### Rust Input

    from_slice(&["-j", "not-a-number", "input.txt"])

    [args::reflect_error] Error: invalid value for `usize`
       ╭─[ <unknown>:1:4 ]
       │
     1 │ -j not-a-number input.txt
       │    ──────┬─────
       │          ╰─────── invalid value for `usize`
    ───╯