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

rs
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,

/// 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

rs
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,

/// 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

rs
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,

/// 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> Remove { /// Name of the remote to remove #[facet(args::positional)] name: String, },
/// List all remotes List { /// Show remote URLs after names #[facet(args::named, args::short)] verbose: bool, }, }

Rust Input

rs
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,

/// 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> Remove { /// Name of the remote to remove #[facet(args::positional)] name: String, },
/// List all remotes List { /// Show remote URLs after names #[facet(args::named, args::short)] verbose: bool, }, }

Rust Input

rs
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,

/// 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> Remove { /// Name of the remote to remove #[facet(args::positional)] name: String, },
/// List all remotes List { /// Show remote URLs after names #[facet(args::named, args::short)] verbose: bool, }, }

Rust Input

rs
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,

/// 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

rs
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> Remove { /// Name of the remote to remove #[facet(args::positional)] name: String, },
/// List all remotes List { /// 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

txt
_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

txt
#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

txt
# 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

rs
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

rs
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

rs
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

rs
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

rs
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

rs
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

rs
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

rs
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> Remove { /// Name of the remote to remove #[facet(args::positional)] name: String, },
/// List all remotes List { /// Show remote URLs after names #[facet(args::named, args::short)] verbose: bool, }, }

Rust Input

rs
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> Remove { /// Name of the remote to remove #[facet(args::positional)] name: String, },
/// List all remotes List { /// Show remote URLs after names #[facet(args::named, args::short)] verbose: bool, }, }

Rust Input

rs
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> Remove { /// Name of the remote to remove #[facet(args::positional)] name: String, },
/// List all remotes List { /// Show remote URLs after names #[facet(args::named, args::short)] verbose: bool, }, }

Rust Input

rs
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

rs
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`
───╯