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 { 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
62impl Default for ArgFlags {
63    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)]
73pub 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
117impl FromStr for ArgSettings {
118    type Err = String;
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)]
147mod test {
148    use super::ArgSettings;
149
150    #[test]
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}