use std::{ops::BitOr, str::FromStr};
use bitflags::bitflags;
#[doc(hidden)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ArgFlags(Flags);
impl Default for ArgFlags {
fn default() -> Self {
Self::empty()
}
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum ArgSettings {
Required,
MultipleValues,
MultipleOccurrences,
#[deprecated(
since = "3.0.0",
note = "Split into `ArgSettings::MultipleOccurrences` (most likely what you want) and `ArgSettings::MultipleValues`"
)]
Multiple,
ForbidEmptyValues,
Global,
Hidden,
TakesValue,
UseValueDelimiter,
NextLineHelp,
RequireDelimiter,
HidePossibleValues,
AllowHyphenValues,
#[deprecated(
since = "3.0.0",
note = "Replaced with `ArgSettings::AllowHyphenValues`"
)]
AllowLeadingHyphen,
RequireEquals,
Last,
HideDefaultValue,
IgnoreCase,
#[deprecated(since = "3.0.0", note = "Replaced with `ArgSettings::IgnoreCase`")]
CaseInsensitive,
#[cfg(feature = "env")]
HideEnv,
#[cfg(feature = "env")]
HideEnvValues,
HiddenShortHelp,
HiddenLongHelp,
AllowInvalidUtf8,
}
bitflags! {
struct Flags: u32 {
const REQUIRED = 1;
const MULTIPLE_OCC = 1 << 1;
const NO_EMPTY_VALS = 1 << 2;
const GLOBAL = 1 << 3;
const HIDDEN = 1 << 4;
const TAKES_VAL = 1 << 5;
const USE_DELIM = 1 << 6;
const NEXT_LINE_HELP = 1 << 7;
const REQ_DELIM = 1 << 9;
const DELIM_NOT_SET = 1 << 10;
const HIDE_POS_VALS = 1 << 11;
const ALLOW_TAC_VALS = 1 << 12;
const REQUIRE_EQUALS = 1 << 13;
const LAST = 1 << 14;
const HIDE_DEFAULT_VAL = 1 << 15;
const CASE_INSENSITIVE = 1 << 16;
#[cfg(feature = "env")]
const HIDE_ENV_VALS = 1 << 17;
const HIDDEN_SHORT_H = 1 << 18;
const HIDDEN_LONG_H = 1 << 19;
const MULTIPLE_VALS = 1 << 20;
const MULTIPLE = Self::MULTIPLE_OCC.bits | Self::MULTIPLE_VALS.bits;
#[cfg(feature = "env")]
const HIDE_ENV = 1 << 21;
const UTF8_NONE = 1 << 22;
const NO_OP = 0;
}
}
impl_settings! { ArgSettings, ArgFlags,
Required("required") => Flags::REQUIRED,
MultipleOccurrences("multipleoccurrences") => Flags::MULTIPLE_OCC,
MultipleValues("multiplevalues") => Flags::MULTIPLE_VALS,
Multiple("multiple") => Flags::MULTIPLE,
ForbidEmptyValues("forbidemptyvalues") => Flags::NO_EMPTY_VALS,
Global("global") => Flags::GLOBAL,
Hidden("hidden") => Flags::HIDDEN,
TakesValue("takesvalue") => Flags::TAKES_VAL,
UseValueDelimiter("usevaluedelimiter") => Flags::USE_DELIM,
NextLineHelp("nextlinehelp") => Flags::NEXT_LINE_HELP,
RequireDelimiter("requiredelimiter") => Flags::REQ_DELIM,
HidePossibleValues("hidepossiblevalues") => Flags::HIDE_POS_VALS,
AllowHyphenValues("allowhyphenvalues") => Flags::ALLOW_TAC_VALS,
AllowLeadingHyphen("allowleadinghypyhen") => Flags::ALLOW_TAC_VALS,
RequireEquals("requireequals") => Flags::REQUIRE_EQUALS,
Last("last") => Flags::LAST,
IgnoreCase("ignorecase") => Flags::CASE_INSENSITIVE,
CaseInsensitive("caseinsensitive") => Flags::CASE_INSENSITIVE,
#[cfg(feature = "env")]
HideEnv("hideenv") => Flags::HIDE_ENV,
#[cfg(feature = "env")]
HideEnvValues("hideenvvalues") => Flags::HIDE_ENV_VALS,
HideDefaultValue("hidedefaultvalue") => Flags::HIDE_DEFAULT_VAL,
HiddenShortHelp("hiddenshorthelp") => Flags::HIDDEN_SHORT_H,
HiddenLongHelp("hiddenlonghelp") => Flags::HIDDEN_LONG_H,
AllowInvalidUtf8("allowinvalidutf8") => Flags::UTF8_NONE
}
#[cfg(test)]
mod test {
use super::ArgSettings;
#[test]
fn arg_settings_fromstr() {
assert_eq!(
"allowhyphenvalues".parse::<ArgSettings>().unwrap(),
ArgSettings::AllowHyphenValues
);
assert_eq!(
"forbidemptyvalues".parse::<ArgSettings>().unwrap(),
ArgSettings::ForbidEmptyValues
);
assert_eq!(
"hidepossiblevalues".parse::<ArgSettings>().unwrap(),
ArgSettings::HidePossibleValues
);
assert_eq!(
"hidden".parse::<ArgSettings>().unwrap(),
ArgSettings::Hidden
);
assert_eq!(
"nextlinehelp".parse::<ArgSettings>().unwrap(),
ArgSettings::NextLineHelp
);
assert_eq!(
"requiredelimiter".parse::<ArgSettings>().unwrap(),
ArgSettings::RequireDelimiter
);
assert_eq!(
"required".parse::<ArgSettings>().unwrap(),
ArgSettings::Required
);
assert_eq!(
"takesvalue".parse::<ArgSettings>().unwrap(),
ArgSettings::TakesValue
);
assert_eq!(
"usevaluedelimiter".parse::<ArgSettings>().unwrap(),
ArgSettings::UseValueDelimiter
);
assert_eq!(
"requireequals".parse::<ArgSettings>().unwrap(),
ArgSettings::RequireEquals
);
assert_eq!("last".parse::<ArgSettings>().unwrap(), ArgSettings::Last);
assert_eq!(
"hidedefaultvalue".parse::<ArgSettings>().unwrap(),
ArgSettings::HideDefaultValue
);
assert_eq!(
"ignorecase".parse::<ArgSettings>().unwrap(),
ArgSettings::IgnoreCase
);
#[cfg(feature = "env")]
assert_eq!(
"hideenv".parse::<ArgSettings>().unwrap(),
ArgSettings::HideEnv
);
#[cfg(feature = "env")]
assert_eq!(
"hideenvvalues".parse::<ArgSettings>().unwrap(),
ArgSettings::HideEnvValues
);
assert_eq!(
"hiddenshorthelp".parse::<ArgSettings>().unwrap(),
ArgSettings::HiddenShortHelp
);
assert_eq!(
"hiddenlonghelp".parse::<ArgSettings>().unwrap(),
ArgSettings::HiddenLongHelp
);
assert_eq!(
"allowinvalidutf8".parse::<ArgSettings>().unwrap(),
ArgSettings::AllowInvalidUtf8
);
assert!("hahahaha".parse::<ArgSettings>().is_err());
}
}