1 // Std 2 #[allow(deprecated, unused_imports)] 3 use std::ascii::AsciiExt; 4 use std::str::FromStr; 5 6 bitflags! { 7 struct Flags: u32 { 8 const REQUIRED = 1; 9 const MULTIPLE = 1 << 1; 10 const EMPTY_VALS = 1 << 2; 11 const GLOBAL = 1 << 3; 12 const HIDDEN = 1 << 4; 13 const TAKES_VAL = 1 << 5; 14 const USE_DELIM = 1 << 6; 15 const NEXT_LINE_HELP = 1 << 7; 16 const R_UNLESS_ALL = 1 << 8; 17 const REQ_DELIM = 1 << 9; 18 const DELIM_NOT_SET = 1 << 10; 19 const HIDE_POS_VALS = 1 << 11; 20 const ALLOW_TAC_VALS = 1 << 12; 21 const REQUIRE_EQUALS = 1 << 13; 22 const LAST = 1 << 14; 23 const HIDE_DEFAULT_VAL = 1 << 15; 24 const CASE_INSENSITIVE = 1 << 16; 25 const HIDE_ENV_VALS = 1 << 17; 26 const HIDDEN_SHORT_H = 1 << 18; 27 const HIDDEN_LONG_H = 1 << 19; 28 } 29 } 30 31 #[doc(hidden)] 32 #[derive(Debug, Clone, Copy)] 33 pub struct ArgFlags(Flags); 34 35 impl ArgFlags { new() -> Self36 pub fn new() -> Self { ArgFlags::default() } 37 38 impl_settings!{ArgSettings, 39 Required => Flags::REQUIRED, 40 Multiple => Flags::MULTIPLE, 41 EmptyValues => Flags::EMPTY_VALS, 42 Global => Flags::GLOBAL, 43 Hidden => Flags::HIDDEN, 44 TakesValue => Flags::TAKES_VAL, 45 UseValueDelimiter => Flags::USE_DELIM, 46 NextLineHelp => Flags::NEXT_LINE_HELP, 47 RequiredUnlessAll => Flags::R_UNLESS_ALL, 48 RequireDelimiter => Flags::REQ_DELIM, 49 ValueDelimiterNotSet => Flags::DELIM_NOT_SET, 50 HidePossibleValues => Flags::HIDE_POS_VALS, 51 AllowLeadingHyphen => Flags::ALLOW_TAC_VALS, 52 RequireEquals => Flags::REQUIRE_EQUALS, 53 Last => Flags::LAST, 54 CaseInsensitive => Flags::CASE_INSENSITIVE, 55 HideEnvValues => Flags::HIDE_ENV_VALS, 56 HideDefaultValue => Flags::HIDE_DEFAULT_VAL, 57 HiddenShortHelp => Flags::HIDDEN_SHORT_H, 58 HiddenLongHelp => Flags::HIDDEN_LONG_H 59 } 60 } 61 62 impl Default for ArgFlags { default() -> Self63 fn default() -> Self { ArgFlags(Flags::EMPTY_VALS | Flags::DELIM_NOT_SET) } 64 } 65 66 /// Various settings that apply to arguments and may be set, unset, and checked via getter/setter 67 /// methods [`Arg::set`], [`Arg::unset`], and [`Arg::is_set`] 68 /// 69 /// [`Arg::set`]: ./struct.Arg.html#method.set 70 /// [`Arg::unset`]: ./struct.Arg.html#method.unset 71 /// [`Arg::is_set`]: ./struct.Arg.html#method.is_set 72 #[derive(Debug, PartialEq, Copy, Clone)] 73 pub enum ArgSettings { 74 /// The argument must be used 75 Required, 76 /// The argument may be used multiple times such as `--flag --flag` 77 Multiple, 78 /// The argument allows empty values such as `--option ""` 79 EmptyValues, 80 /// The argument should be propagated down through all child [`SubCommand`]s 81 /// 82 /// [`SubCommand`]: ./struct.SubCommand.html 83 Global, 84 /// The argument should **not** be shown in help text 85 Hidden, 86 /// The argument accepts a value, such as `--option <value>` 87 TakesValue, 88 /// Determines if the argument allows values to be grouped via a delimiter 89 UseValueDelimiter, 90 /// Prints the help text on the line after the argument 91 NextLineHelp, 92 /// Requires the use of a value delimiter for all multiple values 93 RequireDelimiter, 94 /// Hides the possible values from the help string 95 HidePossibleValues, 96 /// Allows vals that start with a '-' 97 AllowLeadingHyphen, 98 /// Require options use `--option=val` syntax 99 RequireEquals, 100 /// Specifies that the arg is the last positional argument and may be accessed early via `--` 101 /// syntax 102 Last, 103 /// Hides the default value from the help string 104 HideDefaultValue, 105 /// Makes `Arg::possible_values` case insensitive 106 CaseInsensitive, 107 /// Hides ENV values in the help message 108 HideEnvValues, 109 /// The argument should **not** be shown in short help text 110 HiddenShortHelp, 111 /// The argument should **not** be shown in long help text 112 HiddenLongHelp, 113 #[doc(hidden)] RequiredUnlessAll, 114 #[doc(hidden)] ValueDelimiterNotSet, 115 } 116 117 impl FromStr for ArgSettings { 118 type Err = String; from_str(s: &str) -> Result<Self, <Self as FromStr>::Err>119 fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> { 120 match &*s.to_ascii_lowercase() { 121 "required" => Ok(ArgSettings::Required), 122 "multiple" => Ok(ArgSettings::Multiple), 123 "global" => Ok(ArgSettings::Global), 124 "emptyvalues" => Ok(ArgSettings::EmptyValues), 125 "hidden" => Ok(ArgSettings::Hidden), 126 "takesvalue" => Ok(ArgSettings::TakesValue), 127 "usevaluedelimiter" => Ok(ArgSettings::UseValueDelimiter), 128 "nextlinehelp" => Ok(ArgSettings::NextLineHelp), 129 "requiredunlessall" => Ok(ArgSettings::RequiredUnlessAll), 130 "requiredelimiter" => Ok(ArgSettings::RequireDelimiter), 131 "valuedelimiternotset" => Ok(ArgSettings::ValueDelimiterNotSet), 132 "hidepossiblevalues" => Ok(ArgSettings::HidePossibleValues), 133 "allowleadinghyphen" => Ok(ArgSettings::AllowLeadingHyphen), 134 "requireequals" => Ok(ArgSettings::RequireEquals), 135 "last" => Ok(ArgSettings::Last), 136 "hidedefaultvalue" => Ok(ArgSettings::HideDefaultValue), 137 "caseinsensitive" => Ok(ArgSettings::CaseInsensitive), 138 "hideenvvalues" => Ok(ArgSettings::HideEnvValues), 139 "hiddenshorthelp" => Ok(ArgSettings::HiddenShortHelp), 140 "hiddenlonghelp" => Ok(ArgSettings::HiddenLongHelp), 141 _ => Err("unknown ArgSetting, cannot convert from str".to_owned()), 142 } 143 } 144 } 145 146 #[cfg(test)] 147 mod test { 148 use super::ArgSettings; 149 150 #[test] arg_settings_fromstr()151 fn arg_settings_fromstr() { 152 assert_eq!( 153 "allowleadinghyphen".parse::<ArgSettings>().unwrap(), 154 ArgSettings::AllowLeadingHyphen 155 ); 156 assert_eq!( 157 "emptyvalues".parse::<ArgSettings>().unwrap(), 158 ArgSettings::EmptyValues 159 ); 160 assert_eq!( 161 "global".parse::<ArgSettings>().unwrap(), 162 ArgSettings::Global 163 ); 164 assert_eq!( 165 "hidepossiblevalues".parse::<ArgSettings>().unwrap(), 166 ArgSettings::HidePossibleValues 167 ); 168 assert_eq!( 169 "hidden".parse::<ArgSettings>().unwrap(), 170 ArgSettings::Hidden 171 ); 172 assert_eq!( 173 "multiple".parse::<ArgSettings>().unwrap(), 174 ArgSettings::Multiple 175 ); 176 assert_eq!( 177 "nextlinehelp".parse::<ArgSettings>().unwrap(), 178 ArgSettings::NextLineHelp 179 ); 180 assert_eq!( 181 "requiredunlessall".parse::<ArgSettings>().unwrap(), 182 ArgSettings::RequiredUnlessAll 183 ); 184 assert_eq!( 185 "requiredelimiter".parse::<ArgSettings>().unwrap(), 186 ArgSettings::RequireDelimiter 187 ); 188 assert_eq!( 189 "required".parse::<ArgSettings>().unwrap(), 190 ArgSettings::Required 191 ); 192 assert_eq!( 193 "takesvalue".parse::<ArgSettings>().unwrap(), 194 ArgSettings::TakesValue 195 ); 196 assert_eq!( 197 "usevaluedelimiter".parse::<ArgSettings>().unwrap(), 198 ArgSettings::UseValueDelimiter 199 ); 200 assert_eq!( 201 "valuedelimiternotset".parse::<ArgSettings>().unwrap(), 202 ArgSettings::ValueDelimiterNotSet 203 ); 204 assert_eq!( 205 "requireequals".parse::<ArgSettings>().unwrap(), 206 ArgSettings::RequireEquals 207 ); 208 assert_eq!("last".parse::<ArgSettings>().unwrap(), ArgSettings::Last); 209 assert_eq!( 210 "hidedefaultvalue".parse::<ArgSettings>().unwrap(), 211 ArgSettings::HideDefaultValue 212 ); 213 assert_eq!( 214 "caseinsensitive".parse::<ArgSettings>().unwrap(), 215 ArgSettings::CaseInsensitive 216 ); 217 assert_eq!( 218 "hideenvvalues".parse::<ArgSettings>().unwrap(), 219 ArgSettings::HideEnvValues 220 ); 221 assert_eq!( 222 "hiddenshorthelp".parse::<ArgSettings>().unwrap(), 223 ArgSettings::HiddenShortHelp 224 ); 225 assert_eq!( 226 "hiddenlonghelp".parse::<ArgSettings>().unwrap(), 227 ArgSettings::HiddenLongHelp 228 ); 229 assert!("hahahaha".parse::<ArgSettings>().is_err()); 230 } 231 } 232