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