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,
<span style="color:#565f89;">/// Number of parallel jobs to run

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

<span style="color:#565f89;">/// Input file to process

#[facet(args::positional)] input: String,

<span style="color:#565f89;">/// Output file (defaults to stdout)

#[facet(args::positional)] output: Option<String>, }

Rust Input

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

Success

SimpleArgs {
  verbosetrue,
  jobsOption::Some(4),
  input"input.txt",
  outputOption::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,
<span style="color:#565f89;">/// Number of parallel jobs to run

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

<span style="color:#565f89;">/// Input file to process

#[facet(args::positional)] input: String,

<span style="color:#565f89;">/// Output file (defaults to stdout)

#[facet(args::positional)] output: Option<String>, }

Rust Input

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

Success

SimpleArgs {
  verbosefalse,
  jobsOption::Some(4),
  input"input.txt",
  outputOption::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,
<span style="color:#565f89;">/// Number of parallel jobs to run

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

<span style="color:#565f89;">/// Input file to process

#[facet(args::positional)] input: String,

<span style="color:#565f89;">/// Output file (defaults to stdout)

#[facet(args::positional)] output: Option<String>, }

Rust Input

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

Success

SimpleArgs {
  verbosetrue,
  jobsOption::None,
  input"input.txt",
  outputOption::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,
<span style="color:#565f89;">/// 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,

    <span style="color:#565f89;">/// Directory to clone into

#[facet(args::positional)] directory: Option<String>,

    <span style="color:#565f89;">/// Clone only the specified branch

#[facet(args::named, args::short)] branch: Option<String>,

    <span style="color:#565f89;">/// Create a shallow clone with limited history

#[facet(args::named)] depth: Option<usize>, },

<span style="color:#565f89;">/// Show the working tree status

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

    <span style="color:#565f89;">/// Show the branch even in short-format

#[facet(args::named, args::short)] branch: bool, },

<span style="color:#565f89;">/// 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,

    <span style="color:#565f89;">/// URL of the remote repository

#[facet(args::positional)] url: String, },

<span style="color:#565f89;">/// Remove the remote named &lt;name&gt;

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

<span style="color:#565f89;">/// List all remotes

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

Rust Input

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

Success

GitLikeArgs {
  versionfalse,
  commandGitCommand::Status {
    shorttrue,
    branchtrue,
  },
}

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,
<span style="color:#565f89;">/// 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,

    <span style="color:#565f89;">/// Directory to clone into

#[facet(args::positional)] directory: Option<String>,

    <span style="color:#565f89;">/// Clone only the specified branch

#[facet(args::named, args::short)] branch: Option<String>,

    <span style="color:#565f89;">/// Create a shallow clone with limited history

#[facet(args::named)] depth: Option<usize>, },

<span style="color:#565f89;">/// Show the working tree status

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

    <span style="color:#565f89;">/// Show the branch even in short-format

#[facet(args::named, args::short)] branch: bool, },

<span style="color:#565f89;">/// 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,

    <span style="color:#565f89;">/// URL of the remote repository

#[facet(args::positional)] url: String, },

<span style="color:#565f89;">/// Remove the remote named &lt;name&gt;

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

<span style="color:#565f89;">/// 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 {
  versionfalse,
  commandGitCommand::Clone {
    url"https://github.com/user/repo",
    directoryOption::None,
    branchOption::Some("main"),
    depthOption::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,
<span style="color:#565f89;">/// 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,

    <span style="color:#565f89;">/// Directory to clone into

#[facet(args::positional)] directory: Option<String>,

    <span style="color:#565f89;">/// Clone only the specified branch

#[facet(args::named, args::short)] branch: Option<String>,

    <span style="color:#565f89;">/// Create a shallow clone with limited history

#[facet(args::named)] depth: Option<usize>, },

<span style="color:#565f89;">/// Show the working tree status

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

    <span style="color:#565f89;">/// Show the branch even in short-format

#[facet(args::named, args::short)] branch: bool, },

<span style="color:#565f89;">/// 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,

    <span style="color:#565f89;">/// URL of the remote repository

#[facet(args::positional)] url: String, },

<span style="color:#565f89;">/// Remove the remote named &lt;name&gt;

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

<span style="color:#565f89;">/// 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 {
  versionfalse,
  commandGitCommand::Remote {
    actionRemoteAction::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,
<span style="color:#565f89;">/// Number of parallel jobs to run

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

<span style="color:#565f89;">/// Input file to process

#[facet(args::positional)] input: String,

<span style="color:#565f89;">/// Output file (defaults to stdout)

#[facet(args::positional)] output: Option<String>, }

Rust Output

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,
<span style="color:#565f89;">/// Number of parallel jobs to run

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

<span style="color:#565f89;">/// Input file to process

#[facet(args::positional)] input: String,

<span style="color:#565f89;">/// Output file (defaults to stdout)

#[facet(args::positional)] output: Option<String>, }

Rust Input

from_slice(&["--help"])

Error

args::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            ╭────  1 │ --help    · ───┬──    ·    ╰── help requested    ╰────

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,
<span style="color:#565f89;">/// 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,

    <span style="color:#565f89;">/// Directory to clone into

#[facet(args::positional)] directory: Option<String>,

    <span style="color:#565f89;">/// Clone only the specified branch

#[facet(args::named, args::short)] branch: Option<String>,

    <span style="color:#565f89;">/// Create a shallow clone with limited history

#[facet(args::named)] depth: Option<usize>, },

<span style="color:#565f89;">/// Show the working tree status

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

    <span style="color:#565f89;">/// Show the branch even in short-format

#[facet(args::named, args::short)] branch: bool, },

<span style="color:#565f89;">/// 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,

    <span style="color:#565f89;">/// URL of the remote repository

#[facet(args::positional)] url: String, },

<span style="color:#565f89;">/// Remove the remote named &lt;name&gt;

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

<span style="color:#565f89;">/// List all remotes

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

Rust Output

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,
<span style="color:#565f89;">/// Number of parallel jobs

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

<span style="color:#565f89;">/// Package to build

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

<span style="color:#565f89;">/// Build all packages in the workspace

#[facet(args::named)] workspace: bool,

<span style="color:#565f89;">/// Space-separated list of features to enable

#[facet(args::named, args::short)] features: Option<String>,

<span style="color:#565f89;">/// Target triple to build for

#[facet(args::named)] target: Option<String>, }

Rust Output

_cargo-build() {
    local cur prev words cword
    _init_completion || return
local commands=<span style="color:#9ece6a;">&quot;&quot;</span>
local flags=<span style="color:#9ece6a;">&quot;&quot;</span>

flags=<span style="color:#9ece6a;">&quot;--release -r --jobs -j --package -p --workspace --features -F --target&quot;</span>

case &quot;$prev&quot; <span style="color:#bb9af7;">in</span>
    # Add cases <span style="color:#bb9af7;">for</span> flags that take values
    <span style="color:#89ddff;">*</span><span style="color:#a9b1d6;">)</span>
        <span style="color:#a9b1d6;">;;</span>
esac

if <span style="color:#a9b1d6;">[[</span> <span style="color:#9ece6a;">&quot;$cur&quot;</span> == -<span style="color:#89ddff;">*</span> <span style="color:#a9b1d6;">]];</span> then
    COMPREPLY=<span style="color:#a9b1d6;">(</span>$<span style="color:#a9b1d6;">(</span>compgen -W <span style="color:#9ece6a;">&quot;$flags&quot;</span> -- <span style="color:#9ece6a;">&quot;$cur&quot;</span><span style="color:#a9b1d6;">))</span>
elif <span style="color:#a9b1d6;">[[</span> -n <span style="color:#9ece6a;">&quot;$commands&quot;</span> <span style="color:#a9b1d6;">]];</span> then
    COMPREPLY=<span style="color:#a9b1d6;">(</span>$<span style="color:#a9b1d6;">(</span>compgen -W <span style="color:#9ece6a;">&quot;$commands&quot;</span> -- <span style="color:#9ece6a;">&quot;$cur&quot;</span><span style="color:#a9b1d6;">))</span>
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,
<span style="color:#565f89;">/// Number of parallel jobs

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

<span style="color:#565f89;">/// Package to build

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

<span style="color:#565f89;">/// Build all packages in the workspace

#[facet(args::named)] workspace: bool,

<span style="color:#565f89;">/// Space-separated list of features to enable

#[facet(args::named, args::short)] features: Option<String>,

<span style="color:#565f89;">/// Target triple to build for

#[facet(args::named)] target: Option<String>, }

Rust Output

#compdef cargo-build

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

options=<span style="color:#a9b1d6;">(</span>
    <span style="color:#89ddff;">'</span>-r<span style="color:#a9b1d6;">[</span>Build in release mode with optimizations<span style="color:#a9b1d6;">]</span><span style="color:#89ddff;">'</span>
    <span style="color:#89ddff;">'</span>--release<span style="color:#a9b1d6;">[</span>Build in release mode with optimizations<span style="color:#a9b1d6;">]</span><span style="color:#89ddff;">'</span>
    <span style="color:#89ddff;">'</span>-j<span style="color:#a9b1d6;">[</span>Number of parallel jobs<span style="color:#a9b1d6;">]</span><span style="color:#89ddff;">'</span>
    <span style="color:#89ddff;">'</span>--jobs<span style="color:#a9b1d6;">[</span>Number of parallel jobs<span style="color:#a9b1d6;">]</span><span style="color:#89ddff;">'</span>
    <span style="color:#89ddff;">'</span>-p<span style="color:#a9b1d6;">[</span>Package to build<span style="color:#a9b1d6;">]</span><span style="color:#89ddff;">'</span>
    <span style="color:#89ddff;">'</span>--package<span style="color:#a9b1d6;">[</span>Package to build<span style="color:#a9b1d6;">]</span><span style="color:#89ddff;">'</span>
    <span style="color:#89ddff;">'</span>--workspace<span style="color:#a9b1d6;">[</span>Build all packages in the workspace<span style="color:#a9b1d6;">]</span><span style="color:#89ddff;">'</span>
    <span style="color:#89ddff;">'</span>-F<span style="color:#a9b1d6;">[</span>Space-separated list of features to enable<span style="color:#a9b1d6;">]</span><span style="color:#89ddff;">'</span>
    <span style="color:#89ddff;">'</span>--features<span style="color:#a9b1d6;">[</span>Space-separated list of features to enable<span style="color:#a9b1d6;">]</span><span style="color:#89ddff;">'</span>
    <span style="color:#89ddff;">'</span>--target<span style="color:#a9b1d6;">[</span>Target triple to build <span style="color:#bb9af7;">for</span><span style="color:#a9b1d6;">]</span><span style="color:#89ddff;">'</span>
<span style="color:#a9b1d6;">)</span>

_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,
<span style="color:#565f89;">/// Number of parallel jobs

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

<span style="color:#565f89;">/// Package to build

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

<span style="color:#565f89;">/// Build all packages in the workspace

#[facet(args::named)] workspace: bool,

<span style="color:#565f89;">/// Space-separated list of features to enable

#[facet(args::named, args::short)] features: Option<String>,

<span style="color:#565f89;">/// Target triple to build for

#[facet(args::named)] target: Option<String>, }

Rust 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,
<span style="color:#565f89;">/// Number of parallel jobs to run

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

<span style="color:#565f89;">/// Input file to process

#[facet(args::positional)] input: String,

<span style="color:#565f89;">/// Output file (defaults to stdout)

#[facet(args::positional)] output: Option<String>, }

Rust Input

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

Error

args::unknown_long_flag

  × Could not parse CLI arguments    ╭────  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,
<span style="color:#565f89;">/// Number of parallel jobs

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

<span style="color:#565f89;">/// Package to build

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

<span style="color:#565f89;">/// Build all packages in the workspace

#[facet(args::named)] workspace: bool,

<span style="color:#565f89;">/// Space-separated list of features to enable

#[facet(args::named, args::short)] features: Option<String>,

<span style="color:#565f89;">/// Target triple to build for

#[facet(args::named)] target: Option<String>, }

Rust Input

from_slice(&["--releas"])

Error

args::unknown_long_flag

  × Could not parse CLI arguments    ╭────  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,
<span style="color:#565f89;">/// Number of parallel jobs to run

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

<span style="color:#565f89;">/// Input file to process

#[facet(args::positional)] input: String,

<span style="color:#565f89;">/// Output file (defaults to stdout)

#[facet(args::positional)] output: Option<String>, }

Rust Input

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

Error

args::unknown_short_flag

  × Could not parse CLI arguments    ╭────  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,
<span style="color:#565f89;">/// Number of parallel jobs to run

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

<span style="color:#565f89;">/// Input file to process

#[facet(args::positional)] input: String,

<span style="color:#565f89;">/// Output file (defaults to stdout)

#[facet(args::positional)] output: Option<String>, }

Rust Input

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

Error

args::unknown_long_flag

  × Could not parse CLI arguments    ╭────  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,
<span style="color:#565f89;">/// Number of parallel jobs to run

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

<span style="color:#565f89;">/// Input file to process

#[facet(args::positional)] input: String,

<span style="color:#565f89;">/// Output file (defaults to stdout)

#[facet(args::positional)] output: Option<String>, }

Rust Input

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

Error

args::unknown_short_flag

  × Could not parse CLI arguments    ╭────  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,
<span style="color:#565f89;">/// Number of parallel jobs to run

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

<span style="color:#565f89;">/// Input file to process

#[facet(args::positional)] input: String,

<span style="color:#565f89;">/// Output file (defaults to stdout)

#[facet(args::positional)] output: Option<String>, }

Rust Input

from_slice(&["-j"])

Error

args::expected_value

  × Could not parse CLI arguments    ╭────  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,
<span style="color:#565f89;">/// Number of parallel jobs to run

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

<span style="color:#565f89;">/// Input file to process

#[facet(args::positional)] input: String,

<span style="color:#565f89;">/// Output file (defaults to stdout)

#[facet(args::positional)] output: Option<String>, }

Rust Input

from_slice(&["-v"])

Error

args::missing_argument

  × Could not parse CLI arguments    ╭────  1 │ -v     ╰────   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,
<span style="color:#565f89;">/// Number of parallel jobs

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

<span style="color:#565f89;">/// Package to build

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

<span style="color:#565f89;">/// Build all packages in the workspace

#[facet(args::named)] workspace: bool,

<span style="color:#565f89;">/// Space-separated list of features to enable

#[facet(args::named, args::short)] features: Option<String>,

<span style="color:#565f89;">/// Target triple to build for

#[facet(args::named)] target: Option<String>, }

Rust Input

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

Error

args::unexpected_positional

  × Could not parse CLI arguments    ╭────  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,
<span style="color:#565f89;">/// 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,

    <span style="color:#565f89;">/// Directory to clone into

#[facet(args::positional)] directory: Option<String>,

    <span style="color:#565f89;">/// Clone only the specified branch

#[facet(args::named, args::short)] branch: Option<String>,

    <span style="color:#565f89;">/// Create a shallow clone with limited history

#[facet(args::named)] depth: Option<usize>, },

<span style="color:#565f89;">/// Show the working tree status

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

    <span style="color:#565f89;">/// Show the branch even in short-format

#[facet(args::named, args::short)] branch: bool, },

<span style="color:#565f89;">/// 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,

    <span style="color:#565f89;">/// URL of the remote repository

#[facet(args::positional)] url: String, },

<span style="color:#565f89;">/// Remove the remote named &lt;name&gt;

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

<span style="color:#565f89;">/// List all remotes

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

Rust Input

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

Error

args::unknown_subcommand

  × Could not parse CLI arguments    ╭────  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,
<span style="color:#565f89;">/// 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,

    <span style="color:#565f89;">/// Directory to clone into

#[facet(args::positional)] directory: Option<String>,

    <span style="color:#565f89;">/// Clone only the specified branch

#[facet(args::named, args::short)] branch: Option<String>,

    <span style="color:#565f89;">/// Create a shallow clone with limited history

#[facet(args::named)] depth: Option<usize>, },

<span style="color:#565f89;">/// Show the working tree status

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

    <span style="color:#565f89;">/// Show the branch even in short-format

#[facet(args::named, args::short)] branch: bool, },

<span style="color:#565f89;">/// 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,

    <span style="color:#565f89;">/// URL of the remote repository

#[facet(args::positional)] url: String, },

<span style="color:#565f89;">/// Remove the remote named &lt;name&gt;

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

<span style="color:#565f89;">/// List all remotes

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

Rust Input

from_slice(&["--version"])

Error

args::missing_subcommand

  × Could not parse CLI arguments    ╭────  1 │ --version     ╰────   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,
<span style="color:#565f89;">/// 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,

    <span style="color:#565f89;">/// Directory to clone into

#[facet(args::positional)] directory: Option<String>,

    <span style="color:#565f89;">/// Clone only the specified branch

#[facet(args::named, args::short)] branch: Option<String>,

    <span style="color:#565f89;">/// Create a shallow clone with limited history

#[facet(args::named)] depth: Option<usize>, },

<span style="color:#565f89;">/// Show the working tree status

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

    <span style="color:#565f89;">/// Show the branch even in short-format

#[facet(args::named, args::short)] branch: bool, },

<span style="color:#565f89;">/// 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,

    <span style="color:#565f89;">/// URL of the remote repository

#[facet(args::positional)] url: String, },

<span style="color:#565f89;">/// Remove the remote named &lt;name&gt;

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

<span style="color:#565f89;">/// List all remotes

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

Rust Input

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

Error

args::missing_argument

  × Could not parse CLI arguments    ╭────  1 │ remote add origin     ╰────   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,
<span style="color:#565f89;">/// Number of parallel jobs to run

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

<span style="color:#565f89;">/// Input file to process

#[facet(args::positional)] input: String,

<span style="color:#565f89;">/// Output file (defaults to stdout)

#[facet(args::positional)] output: Option<String>, }

Rust Input

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

Error

args::reflect_error

  × Could not parse CLI arguments    ╭────  1 │ -j not-a-number input.txt     ·    ──────┬─────    ·          ╰── invalid value for `usize`    ╰────