getopt3 - command line argument parser for Rust
===============================================
*Version 2.4.0* [MIT Licensed](https://spdx.org/licenses/MIT.html)

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://spdx.org/licenses/MIT.html)
[![Crates.io Version](https://img.shields.io/crates/v/getopt3.svg)](https://crates.io/crates/getopt3)
[![MSRV Crates.io](https://img.shields.io/crates/msrv/getopt3?logo=rust&label=MSRV&labelColor=orange)](https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html)
[![Safe Rust](https://img.shields.io/badge/Rust-safe-brightgreen.svg)](https://doc.rust-lang.org/nomicon/meet-safe-and-unsafe.html)
[![dependency status](https://deps.rs/repo/gitlab/hsn10/getopt3/status.svg)](https://deps.rs/repo/gitlab/hsn10/getopt3)
[![Documentation](https://docs.rs/getopt3/badge.svg)](https://docs.rs/getopt3)
[![Downloads](https://img.shields.io/crates/d/getopt3)](https://crates.io/crates/getopt3/versions)
[![](https://tokei.rs/b1/gitlab/hsn10/getopt3?category=code)](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

### 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. Less than 200 LOC.
1. Zero dependencies.
1. No `unsafe` Rust.
1. Runs on *stable Rust*.
1. `no_std` Rust version in development.
1. 70 unit tests + 1 quick check test + 8 integration tests + 5 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()*.

#### 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/9699919799/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)

#### To be implemented

1. POSIX strict mode. First non option stops option parsing. This is needed for parsing nested command lines.
1. nostd support

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

##### Partialy implemented

1. There is an extension in the *getopt* function specified in POSIX 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 / -? option.
   1. This is partialy implemented. '?' as option is supported but ':' at start of
      option string is reported as error.

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