getopt-iter
A POSIX-compliant command-line option parser for Rust.
This library provides a getopt implementation that closely follows POSIX conventions while also supporting GNU-style long options. It's designed to be flexible, ergonomic, and suitable for both std and no_std environments.
Features
- POSIX-compliant option parsing
- GNU long options with
--optionsyntax - Short option aggregation (
-abcequivalent to-a -b -c) - Flexible argument handling (optional, required, attached, or separate)
- Iterator-based API for ergonomic usage
no_stdsupport with optionalstdfeature- Zero dependencies
- Type-safe option parsing with compile-time checks
- Works with multiple string types (
&str,String,OsString)
Installation
Add this to your Cargo.toml:
[]
= "1.0.1"
For no_std environments, disable default features:
[]
= { = "1.0.1", = false }
Quick Start
use Getopt;
Usage Examples
Basic Option Parsing
use Getopt;
let args = &;
let mut getopt = new;
while let Some = getopt.next
Options with Required Arguments
use Getopt;
let args = &;
let mut getopt = new;
let mut output = None;
let mut verbose = false;
while let Some = getopt.next
println!;
Aggregated Short Options
use Getopt;
// -abc is equivalent to -a -b -c
let args = &;
let mut getopt = new;
assert_eq!;
assert_eq!;
assert_eq!;
Long Options
use Getopt;
let args = &;
let mut getopt = new;
while let Some = getopt.next
Working with std::env::args() or std::env::args_os()
use Getopt;
Error Handling
use Getopt;
// Leading ':' in optstring changes error behavior
let args = &;
let mut getopt = new;
getopt.set_opterr; // Suppress error messages
while let Some = getopt.next
Option String Syntax
The option string (optstring) parameter follows POSIX conventions with GNU extensions:
Basic Syntax
-
Single character: Defines a flag option
"a" // Accepts -a "abc" // Accepts -a, -b, -c -
Character followed by
:: Requires an argument"a:" // -a requires an argument: -a value or -avalue "a:b" // -a takes arg, -b is a flag
Long Options
Use parentheses to define long option names:
"h(help)" // -h or --help
"v(verbose)" // -v or --verbose
"o:(output)" // -o value or --output=value
Special Prefixes
- Leading
:: Suppress error messages, return ':' for missing arguments":abc:" // Silent errors, returns ':' instead of '?'
Examples
// Complex option string
let optstring = "hv(verbose)o:(output)c:(config)d(debug)";
// This accepts:
// -h, --help (no argument)
// -v, --verbose (no argument)
// -o value, --output=value (required argument)
// -c value, --config=value (required argument)
// -d, --debug (no argument)
Special Return Values
The Opt::val() method returns:
- Option character: When a valid option is parsed
'?': When an unknown option is encountered (or any error if optstring doesn't start with:)':': When a required argument is missing (only if optstring starts with:)
Use Opt::erropt() to get the problematic option character when an error occurs.
Program Name Handling
The first argument (argv[0]) is consumed and used as the program name:
use Getopt;
let args = &;
let getopt = new;
assert_eq!; // Basename extracted
no_std Support
The library supports no_std environments. Disable the default std feature:
[]
= { = "1.0.1", = false }
In no_std mode:
- Error messages are not printed (no stderr)
OsStringsupport is unavailable- Core functionality remains the same
API Overview
Opt Structure
Represents a parsed option. Fields are private; use the accessors below.
Methods:
val(&self) -> char— the option character, or'?'/':'for errorserropt(&self) -> Option<char>— the problematic option character when an error occurredarg(&self) -> Option<&str>— the option argument, borrowedinto_arg(self) -> Option<Cow<'static, str>>— the option argument, owned (zero-copy when the argument was a borrowed'staticinput that didn't need to be sliced)
Getopt Structure
Iterator-based option parser:
Methods:
new(args, optstring) -> Self— create a new parser.argsis anyIntoIteratorwhose items implementArgV; the first item is consumed asargv[0].set_opterr(&mut self, opterr: bool)— enable or disable POSIX error messages on stderr (default: enabled; only effective with thestdfeature)next(&mut self) -> Option<Opt>— parse the next option (also available via theIteratorimpl)remaining(self) -> I— consume the parser and return the underlying iterator at its current position to access positional argumentsprog_name(&self) -> &str— the basename ofargv[0]
ArgV Trait
A sealed trait implemented for types that can be used as command-line arguments. Borrowed
implementations are bounded by 'static so they can flow through the parser as Cow::Borrowed
without allocation — a good fit for sources like the argv
crate, which yields &'static OsStr.
| Type | Notes |
|---|---|
&'static str |
Zero-copy |
String |
Zero-copy (takes ownership) |
&'static CStr |
Zero-copy when valid UTF-8; lossy + allocation otherwise |
OsString |
(requires std) Zero-copy when valid UTF-8 |
&'static OsStr |
(requires std) Zero-copy when valid UTF-8 |
Attached arguments (-ofile.txt, --name=value) always allocate, since the slice is tied to the
lifetime of the surrounding argument.
Differences from GNU getopt_long
This implementation deliberately diverges from GNU getopt_long in a few places:
- Long-option syntax is the Solaris-style parenthesis form (
"o:(output)") embedded in the optstring, not a separatestruct optionarray. ::(optional argument) is treated as:(required argument). True optional-argument semantics are not implemented.- No
-W foo→--footranslation. - No
-prefix mode (returning non-options as option code'1'). - No long-option abbreviation. Long options must match exactly.
- No argv permutation. Parsing stops at the first non-option, matching POSIX (and the GNU
+prefix mode) rather than GNU's default permuting behavior. The leading+prefix is accepted for compatibility but has no effect since this is already the default. - Option characters must be ASCII. Non-ASCII bytes in argv are never matched as option characters; they fall through as unknown options or remain part of an attached argument.
Testing
The library includes comprehensive tests covering:
- POSIX compliance scenarios
- GNU extensions
- Error handling
- Edge cases
Run tests with:
For no_std testing:
Fuzzing
This library includes fuzzing targets to ensure robustness and catch potential panics. The fuzzers use cargo-fuzz and libFuzzer.
Install fuzzing tools:
Run all fuzzers for 60 seconds each:
Or run a specific fuzzer:
See the fuzz/README.md for detailed fuzzing documentation.
License
BSD 2-Clause License
Contributing
Contributions are welcome! Please ensure all tests pass and add new tests for any new features.