clap/args/
settings.rs

1// Std
2#[allow(deprecated, unused_imports)]
3use std::ascii::AsciiExt;
4use std::str::FromStr;
5
6bitflags! {
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)]
33pub struct ArgFlags(Flags);
34
35impl ArgFlags {
36    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
64impl Default for ArgFlags {
65    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)]
77pub 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
123impl FromStr for ArgSettings {
124    type Err = String;
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)]
153mod test {
154    use super::ArgSettings;
155
156    #[test]
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}