#![warn(missing_docs)]
#![cfg_attr(not(doc), no_std)]
mod parser;
extern crate alloc;
use alloc::{
format,
string::{String, ToString},
vec::Vec,
};
#[derive(Debug, PartialEq)]
pub struct OptSpecs {
options: Vec<OptSpec>,
flags: Vec<OptFlags>,
option_limit: u32,
other_limit: u32,
unknown_limit: u32,
}
const COUNTER_LIMIT: u32 = u32::MAX;
#[derive(Debug, PartialEq)]
struct OptSpec {
id: String,
name: String,
value_type: OptValue,
}
#[derive(Debug, PartialEq)]
#[non_exhaustive]
pub enum OptValue {
None,
Optional,
OptionalNonEmpty,
Required,
RequiredNonEmpty,
}
#[derive(Debug, PartialEq)]
#[non_exhaustive]
pub enum OptFlags {
OptionsEverywhere,
PrefixMatchLongOptions,
}
impl OptSpecs {
pub fn new() -> Self {
Self {
options: Vec::with_capacity(5),
flags: Vec::with_capacity(2),
option_limit: COUNTER_LIMIT,
other_limit: COUNTER_LIMIT,
unknown_limit: COUNTER_LIMIT,
}
}
pub fn option(mut self, id: &str, name: &str, value_type: OptValue) -> Self {
assert!(
id.chars().count() > 0,
"Option's \"id\" must be at least 1 character long."
);
match name.chars().count() {
0 => panic!("Option's \"name\" must be at least 1 character long."),
1 => assert!(
parser::is_valid_short_option_name(name),
"Not a valid short option name."
),
_ => assert!(
parser::is_valid_long_option_name(name),
"Not a valid long option name."
),
}
if self.options.iter().any(|o| o.name == name) {
panic!("No duplicates allowed for option's \"name\".")
}
self.options.push(OptSpec {
id: id.to_string(),
name: name.to_string(),
value_type,
});
self
}
pub fn flag(mut self, flag: OptFlags) -> Self {
if !self.flags.contains(&flag) {
self.flags.push(flag);
}
self
}
fn is_flag(&self, flag: OptFlags) -> bool {
self.flags.contains(&flag)
}
pub fn limit_options(mut self, limit: u32) -> Self {
self.option_limit = limit;
self
}
pub fn limit_other_args(mut self, limit: u32) -> Self {
self.other_limit = limit;
self
}
pub fn limit_unknown_options(mut self, limit: u32) -> Self {
self.unknown_limit = limit;
self
}
pub fn getopt<I, S>(&self, args: I) -> Args
where
I: IntoIterator<Item = S>,
S: ToString,
{
parser::parse(self, args.into_iter().map(|i| i.to_string()))
}
fn get_short_option_match(&self, name: &str) -> Option<&OptSpec> {
if name.chars().count() != 1 {
return None;
}
self.options.iter().find(|e| e.name == name)
}
fn get_long_option_match(&self, name: &str) -> Option<&OptSpec> {
if name.chars().count() < 2 {
return None;
}
self.options.iter().find(|e| e.name == name)
}
fn get_long_option_prefix_match(&self, name: &str) -> Option<&OptSpec> {
if name.chars().count() < 2 {
return None;
}
if let Some(exact) = self.get_long_option_match(name) {
return Some(exact);
}
let mut result = None;
for e in &self.options {
if e.name.starts_with(name) {
if result.is_none() {
result = Some(e);
} else {
return None;
}
}
}
result
}
}
impl Default for OptSpecs {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, PartialEq)]
pub struct Args {
pub options: Vec<Opt>,
pub other: Vec<String>,
pub unknown: Vec<String>,
}
impl Args {
fn new() -> Self {
Args {
options: Vec::new(),
other: Vec::new(),
unknown: Vec::new(),
}
}
pub fn required_value_missing(&self) -> impl DoubleEndedIterator<Item = &Opt> {
self.options
.iter()
.filter(|opt| opt.value_required && opt.value.is_none())
}
pub fn option_exists(&self, id: &str) -> bool {
self.options.iter().any(|opt| opt.id == id)
}
pub fn options_all<'a>(&'a self, id: &'a str) -> impl DoubleEndedIterator<Item = &'a Opt> {
self.options.iter().filter(move |opt| opt.id == id)
}
pub fn options_first(&self, id: &str) -> Option<&Opt> {
self.options.iter().find(|opt| opt.id == id)
}
pub fn options_last(&self, id: &str) -> Option<&Opt> {
self.options.iter().rev().find(|opt| opt.id == id)
}
pub fn options_value_all<'a>(
&'a self,
id: &'a str,
) -> impl DoubleEndedIterator<Item = &'a String> {
self.options.iter().filter_map(move |opt| {
if opt.id == id {
opt.value.as_ref()
} else {
None
}
})
}
pub fn options_value_first(&self, id: &str) -> Option<&String> {
match self
.options
.iter()
.find(|opt| opt.id == id && opt.value.is_some())
{
Some(o) => o.value.as_ref(),
None => None,
}
}
pub fn options_value_last(&self, id: &str) -> Option<&String> {
match self
.options
.iter()
.rev()
.find(|opt| opt.id == id && opt.value.is_some())
{
Some(o) => o.value.as_ref(),
None => None,
}
}
pub fn unknown_options(&self) -> impl DoubleEndedIterator<Item = String> + '_ {
self.unknown.iter().map(|o| match o.chars().count() {
0 => panic!("zero-length string in Args::unknown"),
1 => format!("-{}", o),
_ => format!("--{}", o),
})
}
}
#[derive(Debug, PartialEq)]
pub struct Opt {
pub id: String,
pub name: String,
pub value_required: bool,
pub value: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec;
#[test]
fn create_optspecs_010() {
let mut spec;
let mut expect;
spec = OptSpecs::new().option("help", "help", OptValue::None);
expect = OptSpec {
id: String::from("help"),
name: String::from("help"),
value_type: OptValue::None,
};
assert_eq!(1, spec.options.len());
assert_eq!(&expect, &spec.options[0]);
assert_eq!(COUNTER_LIMIT, spec.option_limit);
assert_eq!(COUNTER_LIMIT, spec.other_limit);
assert_eq!(COUNTER_LIMIT, spec.unknown_limit);
spec = spec.option("file", "f", OptValue::Optional);
expect = OptSpec {
id: String::from("file"),
name: String::from("f"),
value_type: OptValue::Optional,
};
assert_eq!(2, spec.options.len());
assert_eq!(&expect, &spec.options[1]);
spec = spec.option("file", "file", OptValue::Required);
expect = OptSpec {
id: String::from("file"),
name: String::from("file"),
value_type: OptValue::Required,
};
assert_eq!(3, spec.options.len());
assert_eq!(&expect, &spec.options[2]);
spec = spec.flag(OptFlags::OptionsEverywhere);
assert_eq!(1, spec.flags.len()); assert!(spec.is_flag(OptFlags::OptionsEverywhere));
spec = spec.flag(OptFlags::PrefixMatchLongOptions);
assert_eq!(2, spec.flags.len()); assert!(spec.is_flag(OptFlags::PrefixMatchLongOptions));
spec = spec.flag(OptFlags::OptionsEverywhere);
spec = spec.flag(OptFlags::PrefixMatchLongOptions);
assert_eq!(2, spec.flags.len());
spec = spec.limit_options(9);
spec = spec.limit_other_args(10);
spec = spec.limit_unknown_options(3);
assert_eq!(9, spec.option_limit);
assert_eq!(10, spec.other_limit);
assert_eq!(3, spec.unknown_limit);
}
#[test]
#[should_panic]
fn create_optspecs_020() {
OptSpecs::new().option("", "h", OptValue::None);
}
#[test]
#[should_panic]
fn create_optspecs_030() {
OptSpecs::new()
.option("h", "h", OptValue::None)
.option("h", "h", OptValue::None);
}
#[test]
#[should_panic]
fn create_optspecs_040() {
OptSpecs::new().option("h", "", OptValue::None);
}
#[test]
#[should_panic]
fn create_optspecs_050() {
OptSpecs::new().option("h", "-", OptValue::None);
}
#[test]
#[should_panic]
fn create_optspecs_060() {
OptSpecs::new().option("h", " ", OptValue::None);
}
#[test]
#[should_panic]
fn create_optspecs_070() {
OptSpecs::new().option("h", "hh ", OptValue::None);
}
#[test]
#[should_panic]
fn create_optspecs_080() {
OptSpecs::new().option("h", "hh=hh", OptValue::None);
}
#[test]
fn is_flag() {
let mut spec = OptSpecs::new().flag(OptFlags::OptionsEverywhere);
assert!(spec.is_flag(OptFlags::OptionsEverywhere));
spec = spec.flag(OptFlags::PrefixMatchLongOptions);
assert!(spec.is_flag(OptFlags::PrefixMatchLongOptions));
}
#[test]
fn parsed_output_010() {
let parsed = OptSpecs::new()
.option("help", "h", OptValue::None)
.option("help", "help", OptValue::None)
.option("file", "f", OptValue::Required)
.option("file", "file", OptValue::Required)
.getopt(["-h", "--help", "-f123", "-f", "456", "foo", "bar"]);
assert!(parsed.option_exists("help"));
assert!(parsed.option_exists("file"));
assert!(!parsed.option_exists("x"));
assert_eq!("h", parsed.options_first("help").unwrap().name);
assert_eq!("help", parsed.options_last("help").unwrap().name);
assert_eq!("help", parsed.options_first("help").unwrap().id);
assert_eq!("help", parsed.options_last("help").unwrap().id);
assert_eq!(false, parsed.options_first("help").unwrap().value_required);
assert_eq!(false, parsed.options_last("help").unwrap().value_required);
assert_eq!("f", parsed.options_first("file").unwrap().name);
assert_eq!(
"123",
parsed.options_first("file").unwrap().value.clone().unwrap()
);
assert_eq!(
"456",
parsed.options_last("file").unwrap().value.clone().unwrap()
);
assert_eq!(true, parsed.options_first("file").unwrap().value_required);
assert_eq!("foo", parsed.other[0]);
assert_eq!("bar", parsed.other[1]);
}
#[test]
fn parsed_output_020() {
let parsed = OptSpecs::new()
.limit_options(1)
.limit_other_args(2)
.option("help", "h", OptValue::None)
.getopt(["-h", "foo", "-h"]);
assert_eq!("h", parsed.options_first("help").unwrap().name);
assert_eq!(2, parsed.other.len());
assert_eq!("foo", parsed.other[0]);
assert_eq!("-h", parsed.other[1]);
}
#[test]
fn parsed_output_030() {
let parsed = OptSpecs::new()
.flag(OptFlags::OptionsEverywhere)
.option("help", "h", OptValue::None)
.option("help", "help", OptValue::None)
.option("file", "f", OptValue::Required)
.option("file", "file", OptValue::Required)
.getopt(["-h", "foo", "--help", "--file=123", "bar", "--file", "456"]);
assert_eq!("h", parsed.options_first("help").unwrap().name);
assert_eq!("help", parsed.options_last("help").unwrap().name);
assert_eq!(
"123",
parsed.options_first("file").unwrap().value.clone().unwrap()
);
assert_eq!(
"456",
parsed.options_last("file").unwrap().value.clone().unwrap()
);
assert_eq!("foo", parsed.other[0]);
assert_eq!("bar", parsed.other[1]);
}
#[test]
fn parsed_output_040() {
let parsed = OptSpecs::new()
.option("debug", "d", OptValue::Optional)
.option("verbose", "verbose", OptValue::Optional)
.getopt(["-d1", "-d", "--verbose", "--verbose=123"]);
assert_eq!(
"1",
parsed
.options_first("debug")
.unwrap()
.value
.clone()
.unwrap()
);
assert_eq!(None, parsed.options_last("debug").unwrap().value);
assert_eq!(false, parsed.options_last("debug").unwrap().value_required);
assert_eq!(None, parsed.options_first("verbose").unwrap().value);
assert_eq!(
"123",
parsed
.options_last("verbose")
.unwrap()
.value
.clone()
.unwrap()
);
assert_eq!(
false,
parsed.options_last("verbose").unwrap().value_required
);
}
#[test]
fn parsed_output_050() {
let parsed = OptSpecs::new()
.option("debug", "d", OptValue::Optional)
.getopt(["-abcd", "-adbc"]);
assert_eq!(None, parsed.options_first("debug").unwrap().value);
assert_eq!(
"bc",
parsed.options_last("debug").unwrap().value.clone().unwrap()
);
assert_eq!(3, parsed.unknown.len());
assert_eq!("a", parsed.unknown[0]);
assert_eq!("b", parsed.unknown[1]);
assert_eq!("c", parsed.unknown[2]);
}
#[test]
fn parsed_output_060() {
let parsed = OptSpecs::new()
.option("aaa", "bbb", OptValue::None)
.option("aaa", "c", OptValue::None)
.option("aaa", "d", OptValue::None)
.option("aaa", "eee", OptValue::None)
.getopt(["--bbb", "-cd", "--eee"]);
let m: Vec<&Opt> = parsed.options_all("aaa").collect();
assert_eq!("bbb", m[0].name);
assert_eq!("c", m[1].name);
assert_eq!("d", m[2].name);
assert_eq!("eee", m[3].name);
}
#[test]
fn parsed_output_070() {
let parsed = OptSpecs::new()
.flag(OptFlags::PrefixMatchLongOptions)
.option("version", "version", OptValue::None)
.option("verbose", "verbose", OptValue::None)
.getopt(["--ver", "--verb", "--versi", "--verbose"]);
assert_eq!("ver", parsed.unknown[0]);
assert_eq!("verb", parsed.options_first("verbose").unwrap().name);
assert_eq!("verbose", parsed.options_last("verbose").unwrap().name);
assert_eq!("version", parsed.options_first("version").unwrap().id);
assert_eq!("versi", parsed.options_first("version").unwrap().name);
}
#[test]
fn parsed_output_080() {
let parsed = OptSpecs::new()
.option("version", "version", OptValue::None)
.option("verbose", "verbose", OptValue::None)
.getopt(["--version", "--ver", "--verb", "--versi", "--verbose"]);
assert_eq!("ver", parsed.unknown[0]);
assert_eq!("verb", parsed.unknown[1]);
assert_eq!("versi", parsed.unknown[2]);
assert_eq!("version", parsed.options_first("version").unwrap().name);
assert_eq!("verbose", parsed.options_first("verbose").unwrap().name);
}
#[test]
fn parsed_output_085() {
let parsed = OptSpecs::new()
.flag(OptFlags::PrefixMatchLongOptions)
.option("foo1", "foo", OptValue::None)
.option("foo2", "foo-longer", OptValue::None)
.getopt(["--fo", "--foo", "--foo-", "--foo-longer"]);
assert_eq!("fo", parsed.unknown[0]);
assert_eq!("foo", parsed.options_first("foo1").unwrap().name);
assert_eq!("foo", parsed.options_last("foo1").unwrap().name);
assert_eq!("foo-", parsed.options_first("foo2").unwrap().name);
assert_eq!("foo-longer", parsed.options_last("foo2").unwrap().name);
}
#[test]
fn parsed_output_090() {
let parsed = OptSpecs::new()
.flag(OptFlags::OptionsEverywhere)
.option("help", "h", OptValue::None)
.option("file", "file", OptValue::Required)
.getopt(["-h", "foo", "--file=123", "--", "bar", "--file", "456"]);
assert_eq!("h", parsed.options_first("help").unwrap().name);
assert_eq!("file", parsed.options_first("file").unwrap().name);
assert_eq!(
"123",
parsed.options_first("file").unwrap().value.clone().unwrap()
);
assert_eq!(4, parsed.other.len());
assert_eq!("foo", parsed.other[0]);
assert_eq!("bar", parsed.other[1]);
assert_eq!("--file", parsed.other[2]);
assert_eq!("456", parsed.other[3]);
}
#[test]
fn parsed_output_100() {
let parsed = OptSpecs::new()
.option("file", "file", OptValue::Required)
.getopt(["--file=", "--file"]);
assert_eq!(true, parsed.options_first("file").unwrap().value_required);
assert_eq!(
"",
parsed.options_first("file").unwrap().value.clone().unwrap()
);
assert_eq!(None, parsed.options_last("file").unwrap().value);
}
#[test]
fn parsed_output_110() {
let parsed = OptSpecs::new()
.option("file", "f", OptValue::Required)
.option("debug", "d", OptValue::Required)
.getopt(["-fx", "-d", "", "-f"]);
assert_eq!(true, parsed.options_first("file").unwrap().value_required);
assert_eq!(
"x",
parsed.options_first("file").unwrap().value.clone().unwrap()
);
assert_eq!(None, parsed.options_last("file").unwrap().value);
assert_eq!(
"",
parsed
.options_first("debug")
.unwrap()
.value
.clone()
.unwrap()
);
}
#[test]
fn parsed_output_120() {
let parsed = OptSpecs::new()
.option("file", "f", OptValue::Required)
.option("debug", "d", OptValue::Required)
.getopt(["-f123", "-d", "", "-f", "456", "-f"]);
let f: Vec<&String> = parsed.options_value_all("file").collect();
assert_eq!(2, f.len());
assert_eq!("123", f[0]);
assert_eq!("456", f[1]);
let d: Vec<&String> = parsed.options_value_all("debug").collect();
assert_eq!(1, d.len());
assert_eq!("", d[0]);
assert_eq!(None, parsed.options_last("file").unwrap().value);
let m: Vec<&Opt> = parsed.required_value_missing().collect();
assert_eq!(1, m.len());
assert_eq!("f", m[0].name);
}
#[test]
fn parsed_output_125() {
let parsed = OptSpecs::new()
.option("file", "f", OptValue::Required)
.option("debug", "d", OptValue::RequiredNonEmpty)
.getopt(["-f123", "-d", "", "-f", "456", "-f"]);
let f: Vec<&String> = parsed.options_value_all("file").collect();
assert_eq!(2, f.len());
assert_eq!("123", f[0]);
assert_eq!("456", f[1]);
let d: Vec<&String> = parsed.options_value_all("debug").collect();
assert_eq!(0, d.len());
assert_eq!(None, parsed.options_last("file").unwrap().value);
let m: Vec<&Opt> = parsed.required_value_missing().collect();
assert_eq!(2, m.len());
assert_eq!("d", m[0].name);
assert_eq!("f", m[1].name);
}
#[test]
fn parsed_output_130() {
let parsed = OptSpecs::new()
.option("file", "file", OptValue::Required)
.option("debug", "debug", OptValue::Required)
.getopt(["--file=123", "--debug", "", "--file", "456", "--file"]);
let f: Vec<&String> = parsed.options_value_all("file").collect();
assert_eq!(2, f.len());
assert_eq!("123", f[0]);
assert_eq!("456", f[1]);
let d: Vec<&String> = parsed.options_value_all("debug").collect();
assert_eq!(1, d.len());
assert_eq!("", d[0]);
assert_eq!(None, parsed.options_last("file").unwrap().value);
let m: Vec<&Opt> = parsed.required_value_missing().collect();
assert_eq!(1, m.len());
assert_eq!("file", m[0].name);
}
#[test]
fn parsed_output_135() {
let parsed = OptSpecs::new()
.option("file", "file", OptValue::RequiredNonEmpty)
.option("debug", "debug", OptValue::RequiredNonEmpty)
.getopt(["--file=123", "--debug", "", "--file", "456", "--file="]);
let f: Vec<&String> = parsed.options_value_all("file").collect();
assert_eq!(2, f.len());
assert_eq!("123", f[0]);
assert_eq!("456", f[1]);
let d: Vec<&String> = parsed.options_value_all("debug").collect();
assert_eq!(0, d.len());
assert_eq!(None, parsed.options_last("file").unwrap().value);
let m: Vec<&Opt> = parsed.required_value_missing().collect();
assert_eq!(2, m.len());
assert_eq!("debug", m[0].name);
assert_eq!("file", m[1].name);
}
#[test]
fn parsed_output_137() {
let parsed = OptSpecs::new()
.option("debug", "d", OptValue::OptionalNonEmpty)
.option("debug", "debug", OptValue::OptionalNonEmpty)
.getopt([
"-d",
"-d123",
"--debug",
"--debug=",
"--debug=456",
"--debug=",
]);
let d: Vec<&String> = parsed.options_value_all("debug").collect();
assert_eq!(2, d.len());
assert_eq!("123", d[0]);
assert_eq!("456", d[1]);
assert_eq!("123", parsed.options_value_first("debug").unwrap());
assert_eq!("456", parsed.options_value_last("debug").unwrap());
}
#[test]
fn parsed_output_140() {
let parsed = OptSpecs::new()
.flag(OptFlags::OptionsEverywhere)
.option("debug", "d", OptValue::Optional)
.option("debug", "debug", OptValue::Optional)
.getopt([
"-d",
"-d123",
"-d",
"--debug",
"--debug=",
"foo",
"--debug=456",
"-d",
]);
let d: Vec<&Opt> = parsed.options_all("debug").collect();
assert_eq!(7, d.len());
let d: Vec<&String> = parsed.options_value_all("debug").collect();
assert_eq!(3, d.len());
assert_eq!("123", d[0]);
assert_eq!("", d[1]);
assert_eq!("456", d[2]);
assert_eq!("123", parsed.options_value_first("debug").unwrap());
assert_eq!("456", parsed.options_value_last("debug").unwrap());
assert_eq!(None, parsed.options_value_first("not-at-all"));
assert_eq!(None, parsed.options_value_last("not-at-all"));
assert_eq!("foo", parsed.other[0]);
}
#[test]
fn parsed_output_150() {
let parsed = OptSpecs::new().limit_unknown_options(6).getopt([
"-abcd",
"-e",
"--debug",
"-x", "--",
"--debug=",
"foo",
"--debug=456",
]);
assert_eq!(0, parsed.options.len());
assert_eq!(3, parsed.other.len());
assert_eq!(6, parsed.unknown.len());
assert_eq!(vec!["a", "b", "c", "d", "e", "debug"], parsed.unknown);
}
#[test]
fn parsed_output_160() {
let parsed = OptSpecs::new()
.option("file", "file", OptValue::Required)
.getopt(["--file", "--", "--", "--"]);
assert_eq!(
"--",
parsed.options_first("file").unwrap().value.clone().unwrap()
);
assert_eq!(1, parsed.other.len());
assert_eq!("--", parsed.other[0]);
assert_eq!(0, parsed.required_value_missing().count());
}
#[test]
fn parsed_output_170() {
let parsed = OptSpecs::new().getopt(["foo", "bar"]);
assert_eq!(None, parsed.options_first("not-at-all"));
assert_eq!(None, parsed.options_last("not-at-all"));
}
#[test]
fn parsed_output_180() {
let parsed = OptSpecs::new()
.limit_unknown_options(3)
.option("bar", "bar", OptValue::None)
.getopt(["-aaa", "--foo", "--foo", "--bar=", "--bar=", "-x"]);
assert_eq!(3, parsed.unknown.len());
assert_eq!("a", parsed.unknown[0]);
assert_eq!("foo", parsed.unknown[1]);
assert_eq!("bar=", parsed.unknown[2]);
}
#[test]
fn parsed_output_190() {
let parsed = OptSpecs::new()
.option("äiti", "äiti", OptValue::Required)
.option("€uro", "€uro", OptValue::Required)
.getopt(["--äiti=ööö", "--€uro", "€€€", "--äiti", "ää", "--äiti"]);
let a: Vec<&String> = parsed.options_value_all("äiti").collect();
assert_eq!(2, a.len());
assert_eq!("ööö", a[0]);
assert_eq!("ää", a[1]);
assert_eq!("ööö", parsed.options_value_first("äiti").unwrap());
assert_eq!("ää", parsed.options_value_last("äiti").unwrap());
let e: Vec<&String> = parsed.options_value_all("€uro").collect();
assert_eq!(1, e.len());
assert_eq!("€€€", e[0]);
assert_eq!("€€€", parsed.options_value_first("€uro").unwrap());
assert_eq!("€€€", parsed.options_value_last("€uro").unwrap());
assert_eq!(None, parsed.options_last("äiti").unwrap().value);
let m: Vec<&Opt> = parsed.required_value_missing().collect();
assert_eq!(1, m.len());
assert_eq!("äiti", m[0].name);
assert_eq!(None, m[0].value);
}
#[test]
fn parsed_output_195() {
let parsed = OptSpecs::new().getopt(["-ä€", "--€uro", "äää", "€€€"]);
assert_eq!(2, parsed.other.len());
assert_eq!("äää", parsed.other[0]);
assert_eq!("€€€", parsed.other[1]);
assert_eq!(3, parsed.unknown.len());
assert_eq!("ä", parsed.unknown[0]);
assert_eq!("€", parsed.unknown[1]);
assert_eq!("€uro", parsed.unknown[2]);
}
#[test]
fn parsed_output_200() {
let parsed = OptSpecs::new().limit_other_args(5).getopt(1..10);
assert_eq!(5, parsed.other.len());
assert_eq!(vec!["1", "2", "3", "4", "5"], parsed.other);
}
#[test]
fn parsed_output_210() {
let parsed = OptSpecs::new().limit_other_args(0).getopt(1..10);
assert_eq!(0, parsed.other.len());
}
#[test]
fn parsed_output_220() {
let parsed = OptSpecs::new()
.option("file", "f", OptValue::Required)
.option("file", "file", OptValue::Required)
.option("help", "help", OptValue::None)
.limit_options(3)
.limit_other_args(1)
.limit_unknown_options(3)
.getopt([
"--unknown",
"--help=",
"-ab",
"-f",
"one",
"-ftwo",
"--file",
"three",
"--file",
"four",
"other1",
"other2",
]);
assert_eq!(3, parsed.options.len());
assert_eq!(
vec!["one", "two", "three"],
parsed.options_value_all("file").collect::<Vec<&String>>()
);
assert_eq!(1, parsed.other.len());
assert_eq!("other1", parsed.other[0]);
assert_eq!(3, parsed.unknown.len());
assert_eq!(vec!["unknown", "help=", "a"], parsed.unknown);
}
#[test]
fn parsed_output_230() {
let parsed = OptSpecs::new()
.option("file", "f", OptValue::Required)
.option("file", "file", OptValue::Required)
.limit_options(3)
.getopt(["-f", "one", "-ftwo", "--file=three", "--unknown"]);
assert_eq!(
vec!["one", "two", "three"],
parsed.options_value_all("file").collect::<Vec<&String>>()
);
assert_eq!(1, parsed.unknown.len());
assert_eq!("unknown", parsed.unknown[0]);
}
#[test]
fn parsed_output_240() {
let parsed = OptSpecs::new()
.option("help", "h", OptValue::None)
.limit_options(3)
.getopt(["-xhhhh"]);
assert_eq!(3, parsed.options.len());
assert!(parsed.options_first("help").is_some());
assert_eq!(1, parsed.unknown.len());
assert_eq!("x", parsed.unknown[0]);
}
#[test]
fn parsed_output_250() {
let parsed = OptSpecs::new()
.option("help", "h", OptValue::None)
.limit_options(3)
.getopt(["-x", "-h", "-h", "-h", "-h"]);
assert_eq!(3, parsed.options.len());
assert!(parsed.options_first("help").is_some());
assert_eq!(1, parsed.unknown.len());
assert_eq!("x", parsed.unknown[0]);
}
#[test]
fn parsed_output_260() {
let parsed = OptSpecs::new()
.option("help", "h", OptValue::None)
.limit_options(3)
.getopt(["-x", "-h", "-h", "--", "-h", "-h"]);
assert_eq!(2, parsed.options.len());
assert!(parsed.options_first("help").is_some());
assert_eq!(2, parsed.other.len());
assert_eq!(vec!["-h", "-h"], parsed.other);
assert_eq!(1, parsed.unknown.len());
assert_eq!("x", parsed.unknown[0]);
}
#[test]
fn parsed_output_270() {
let parsed = OptSpecs::new()
.flag(OptFlags::OptionsEverywhere)
.option("help", "h", OptValue::None)
.option("file", "f", OptValue::Required)
.limit_options(1)
.limit_other_args(2)
.limit_unknown_options(1)
.getopt(["bar", "-habf", "123", "foo"]);
assert!(parsed.options_first("help").is_some());
assert!(parsed.options_first("file").is_none());
assert_eq!(2, parsed.other.len());
assert_eq!("bar", parsed.other[0]);
assert_eq!("foo", parsed.other[1]);
assert_eq!(1, parsed.unknown.len());
assert_eq!("a", parsed.unknown[0]);
}
#[test]
fn parsed_output_280() {
let parsed = OptSpecs::new()
.flag(OptFlags::OptionsEverywhere)
.option("help", "help", OptValue::None)
.option("file", "file", OptValue::Required)
.limit_options(1)
.limit_other_args(2)
.limit_unknown_options(1)
.getopt(["bar", "--help", "-ab", "--file", "123", "foo"]);
assert!(parsed.options_first("help").is_some());
assert!(parsed.options_first("file").is_none());
assert_eq!(2, parsed.other.len());
assert_eq!("bar", parsed.other[0]);
assert_eq!("foo", parsed.other[1]);
assert_eq!(1, parsed.unknown.len());
assert_eq!("a", parsed.unknown[0]);
}
#[test]
fn parsed_output_290() {
let parsed = OptSpecs::new()
.option("file", "f", OptValue::RequiredNonEmpty)
.option("debug", "d", OptValue::RequiredNonEmpty)
.getopt(["-f1", "-d", "", "-f", "", "-f", "2", "-f"]);
let mut i = parsed.options_all("file").rev();
assert_eq!("f", i.next().unwrap().name);
assert_eq!("f", i.next().unwrap().name);
assert_eq!("f", i.next().unwrap().name);
assert_eq!("f", i.next().unwrap().name);
assert_eq!(None, i.next());
let mut i = parsed.options_all("debug").rev();
assert_eq!("d", i.next().unwrap().name);
assert_eq!(None, i.next());
let mut i = parsed.options_value_all("file").rev();
assert_eq!("2", i.next().unwrap());
assert_eq!("1", i.next().unwrap());
assert_eq!(None, i.next());
let mut i = parsed.required_value_missing().rev();
assert_eq!("f", i.next().unwrap().name);
assert_eq!("f", i.next().unwrap().name);
assert_eq!("d", i.next().unwrap().name);
assert_eq!(None, i.next());
}
#[test]
fn parsed_output_300() {
let parsed = OptSpecs::new()
.option("debug", "d", OptValue::None)
.getopt(["-aä€d", "--föo"]);
assert_eq!(4, parsed.unknown.len());
let mut u = parsed.unknown_options();
assert_eq!("-a", u.next().unwrap());
assert_eq!("-ä", u.next().unwrap());
assert_eq!("-€", u.next().unwrap());
assert_eq!("--föo", u.next().unwrap());
assert_eq!(None, u.next());
let u = parsed.unknown_options().collect::<Vec<String>>();
assert_eq!(vec!["-a", "-ä", "-€", "--föo"], u);
}
}