getopt3 - command line argument parser for Rust
===============================================
*Version 2.6.0* [MIT Licensed](https://spdx.org/licenses/MIT.html)
[](https://spdx.org/licenses/MIT.html)
[](https://crates.io/crates/getopt3)
[](https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html)
[](https://doc.rust-lang.org/nomicon/meet-safe-and-unsafe.html)
[](https://deps.rs/repo/gitlab/hsn10/getopt3)
[](https://docs.rs/getopt3)
[](https://crates.io/crates/getopt3/versions)
[](https://github.com/XAMPPRocky/tokei)
Features
--------
1. GNU argument parsing rules. Options can be anywhere in command line before --
1. double dash -- support. Anything after -- is not treated as options.
1. Multiple options not requiring argument can be chained together.
-abc is the same as -a -b -c
1. Last chained option can have an argument.
-abcpasta is the same as -a -b -c pasta
1. Argument does not require space. -wfile is same as -w file
1. Parsing fails only if *optstring* is invalid.
### Code quality
1. [MSRV 1.56](https://blog.rust-lang.org/2021/10/21/Rust-1.56.0/), accessible from entire *Rust 2021 Edition*.
1. Rust port of well tested [Scala getopt](https://gitlab.com/hsn10/getopt) code.
1. Small code size, only 229 LOC.
1. Zero dependencies.
1. No `unsafe` Rust.
1. Runs on entire *stable 2021 Edition Rust*.
1. 70 unit tests + 1 quick check test + 7 integration tests + 6 doc tests.
Usage
-----
#### 1. Create getopt instance
let g = **getopt3::new**(_arguments_, _optstring_)
getopt3::new constructor arguments:
1. _arguments_ command line arguments. Can be anything what can be converted to
Iterator over String. You can use `std::env::args()` but you need to skip first
argument because its executable name. It can be done manually or by calling `hideBin`
utility function which strips its first argument.
2. _optstring_ is a anything providing `AsRef <str>`. optstring is containing the legitimate option characters.
Valid option characters are alphanumeric plus '?'.
If such a character is followed by a colon, the option requires an
argument.
##### Returned value:
1. Function returns `Result <getopt>`.
2. `Result` wraps parsing errors and *getopt* structure.
3. Parsing can fail *only if* optstring is invalid.
4. If required argument is missing function *new()* won't fail.
Call *validate()* on parsed result for optional argument checking.
#### 2. Check parsed options
*getopt* structure returned by constructor has following public members:
1. _arguments_ : `Vec <String>` command line arguments with options removed
2. _options_map_ : `HashMap <char, bool>` map of recognized options. option -\> have_argument
3. _options_ : `HashMap <char, String>` options parsed. If option do not have argument, it is mapped to "" `String`,
otherwise it is mapped to its argument as `String`.
Structure *getopt* supports `IntoIterator` and can transform itself into `Iterator`
over supplied command line arguments.
It supports consuming itself or use self immutable reference for enumerating arguments.
*getopt.iter()* returns `Iterator` over pub field _arguments_ without consuming itself.
*getopt.len()* returns number of command line arguments.
It's convience shortcut for *getopt.arguments.len()*.
*getopt.get()* returns value of command line option.
It's convience shortcut for *getopt.options.get()*.
*getopt.has()* returns if option got supplied on command line.
It's convience shortcut for *getopt.options.contains_key()*.
*getopt\[usize\] returns nth command line argument.
It's convience shortcut for *getopt.arguments.index()*.
#### 3. Optional - Check if correct options were provided
You can run strict parse checks by calling *validate(getopt)* function.
This function returns back `Result` with supplied *getopt instance* on success or
error as `String`. It can detect if unknown options were encountered or
required arguments are missing.
Example
-------
```rust
use std::env::args;
use getopt3::hideBin;
let rc = getopt3::new(hideBin(args()), "ab:c");
if let Ok(g) = rc {
// command line options parsed sucessfully
if let Some(arg) = g.options.get(&'b') {
// handle b argument stored in arg
};
};
```
#### Reference
1. [POSIX getopt](https://pubs.opengroup.org/onlinepubs/9799919799/functions/getopt.html) function.
1. [GNU libc getopt](https://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html) function.
1. [OpenBSD getopt](https://man.openbsd.org/getopt.3)
1. [FreeBSD getopt](https://man.freebsd.org/cgi/man.cgi?query=getopt&apropos=0&sektion=3&arch=default&format=html)
#### Known getopt extensions
##### Fully implemented
1. GNU getopt parsing rules.
1. Options can be anywhere in command line before --
1. double dash -- support. Anything after -- is not treated as options.
1. POSIX extension in the *getopt* function where the argument string
specification can start with a colon (:). When the option string begins with
a colon, it modifies the behavior of getopt to handle error cases differently.
Specifically, it suppresses the default error messages that getopt prints
when it encounters an unrecognized option or a missing argument,
and it returns : instead of ? for these error cases. This allows using ? as
option because its possible to spot difference unknown option and -? option.
1. Extension is implemented in way that '?' as option is always supported. ':' at start of
option string is fully optional and have no effect on activating this extension.
##### Not implemented
1. Two colons in optstring indicates that the argument is optional.
This is an extension not covered by POSIX.
This will change only *validate* function because we do not report errors in *getopt3::new*
if required argument is missing.
1. In GNU getopt, if the option string (optstring) begins with a + character,
it triggers POSIX-compatible parsing. This means that the first non-option
argument will stop option parsing, similar to how setting the POSIXLY_CORRECT
environment variable behaves.
#### Possible future developments
Some code for these features exists, but development is paused.
Partially implemented code is not compiled during normal build
and can't be enabled in stock crate using features.
1. `no_std` Rust version in development.
1. `posix` strict mode. First non option stops option parsing. This is needed for parsing nested command lines.