Struct clap::ArgMatches

source ·
pub struct ArgMatches { /* private fields */ }
Expand description

Container for parse results.

Used to get information about the arguments that were supplied to the program at runtime by the user. New instances of this struct are obtained by using the Command::get_matches family of methods.

Examples

let matches = Command::new("MyApp")
    .arg(Arg::new("out")
        .long("output")
        .required(true)
        .action(ArgAction::Set)
        .default_value("-"))
    .arg(Arg::new("cfg")
        .short('c')
        .action(ArgAction::Set))
    .get_matches(); // builds the instance of ArgMatches

// to get information about the "cfg" argument we created, such as the value supplied we use
// various ArgMatches methods, such as [ArgMatches::get_one]
if let Some(c) = matches.get_one::<String>("cfg") {
    println!("Value for -c: {}", c);
}

// The ArgMatches::get_one method returns an Option because the user may not have supplied
// that argument at runtime. But if we specified that the argument was "required" as we did
// with the "out" argument, we can safely unwrap because `clap` verifies that was actually
// used at runtime.
println!("Value for --output: {}", matches.get_one::<String>("out").unwrap());

// You can check the presence of an argument's values
if matches.contains_id("out") {
    // However, if you want to know where the value came from
    if matches.value_source("out").expect("checked contains_id") == ValueSource::CommandLine {
        println!("`out` set by user");
    } else {
        println!("`out` is defaulted");
    }
}

Implementations§

Gets the value of a specific option or positional argument.

i.e. an argument that takes an additional value at runtime.

Returns an error if the wrong type was used.

Returns None if the option wasn’t present.

NOTE: This will always return Some(value) if default_value has been set. ArgMatches::value_source can be used to check if a value is present at runtime.

Panic

If the argument definition and access mismatch. To handle this case programmatically, see ArgMatches::try_get_one.

Examples
let m = Command::new("myapp")
    .arg(Arg::new("port")
        .value_parser(value_parser!(usize))
        .action(ArgAction::Set)
        .required(true))
    .get_matches_from(vec!["myapp", "2020"]);

let port: usize = *m
    .get_one("port")
    .expect("`port`is required");
assert_eq!(port, 2020);
Examples found in repository?
src/parser/matches/arg_matches.rs (line 143)
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
    pub fn get_count(&self, id: &str) -> u8 {
        *self
            .get_one::<u8>(id)
            .expect("ArgAction::Count is defaulted")
    }

    /// Gets the value of a specific [`ArgAction::SetTrue`][crate::ArgAction::SetTrue] or [`ArgAction::SetFalse`][crate::ArgAction::SetFalse] flag
    ///
    /// # Panic
    ///
    /// If the argument's action is not [`ArgAction::SetTrue`][crate::ArgAction::SetTrue] or [`ArgAction::SetFalse`][crate::ArgAction::SetFalse]
    ///
    /// # Examples
    ///
    /// ```rust
    /// # use clap::Command;
    /// # use clap::Arg;
    /// let cmd = Command::new("mycmd")
    ///     .arg(
    ///         Arg::new("flag")
    ///             .long("flag")
    ///             .action(clap::ArgAction::SetTrue)
    ///     );
    ///
    /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap();
    /// assert!(matches.contains_id("flag"));
    /// assert_eq!(
    ///     matches.get_flag("flag"),
    ///     true
    /// );
    /// ```
    #[cfg_attr(debug_assertions, track_caller)]
    pub fn get_flag(&self, id: &str) -> bool {
        *self
            .get_one::<bool>(id)
            .expect("ArgAction::SetTrue / ArgAction::SetFalse is defaulted")
    }
More examples
Hide additional examples
src/parser/parser.rs (line 1267)
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
    fn react(
        &self,
        ident: Option<Identifier>,
        source: ValueSource,
        arg: &Arg,
        mut raw_vals: Vec<OsString>,
        mut trailing_idx: Option<usize>,
        matcher: &mut ArgMatcher,
    ) -> ClapResult<ParseResult> {
        ok!(self.resolve_pending(matcher));

        debug!(
            "Parser::react action={:?}, identifier={:?}, source={:?}",
            arg.get_action(),
            ident,
            source
        );

        // Process before `default_missing_values` to avoid it counting as values from the command
        // line
        if source == ValueSource::CommandLine {
            ok!(self.verify_num_args(arg, &raw_vals));
        }

        if raw_vals.is_empty() {
            // We assume this case is valid: require equals, but min_vals == 0.
            if !arg.default_missing_vals.is_empty() {
                debug!("Parser::react: has default_missing_vals");
                trailing_idx = None;
                raw_vals.extend(
                    arg.default_missing_vals
                        .iter()
                        .map(|s| s.as_os_str().to_owned()),
                );
            }
        }

        if let Some(val_delim) = arg.get_value_delimiter() {
            if self.cmd.is_dont_delimit_trailing_values_set() && trailing_idx == Some(0) {
                // Nothing to do
            } else {
                let mut split_raw_vals = Vec::with_capacity(raw_vals.len());
                for (i, raw_val) in raw_vals.into_iter().enumerate() {
                    let raw_val = RawOsString::new(raw_val);
                    if !raw_val.contains(val_delim)
                        || (self.cmd.is_dont_delimit_trailing_values_set()
                            && trailing_idx == Some(i))
                    {
                        split_raw_vals.push(raw_val.into_os_string());
                    } else {
                        split_raw_vals
                            .extend(raw_val.split(val_delim).map(|x| x.to_os_str().into_owned()));
                    }
                }
                raw_vals = split_raw_vals
            }
        }

        match arg.get_action() {
            ArgAction::Set => {
                if source == ValueSource::CommandLine
                    && matches!(ident, Some(Identifier::Short) | Some(Identifier::Long))
                {
                    // Record flag's index
                    self.cur_idx.set(self.cur_idx.get() + 1);
                    debug!("Parser::react: cur_idx:={}", self.cur_idx.get());
                }
                if matcher.remove(arg.get_id())
                    && !(self.cmd.is_args_override_self() || arg.overrides.contains(arg.get_id()))
                {
                    return Err(ClapError::argument_conflict(
                        self.cmd,
                        arg.to_string(),
                        vec![arg.to_string()],
                        Usage::new(self.cmd).create_usage_with_title(&[]),
                    ));
                }
                self.start_custom_arg(matcher, arg, source);
                ok!(self.push_arg_values(arg, raw_vals, matcher));
                if cfg!(debug_assertions) && matcher.needs_more_vals(arg) {
                    debug!(
                        "Parser::react not enough values passed in, leaving it to the validator to complain",
                    );
                }
                Ok(ParseResult::ValuesDone)
            }
            ArgAction::Append => {
                if source == ValueSource::CommandLine
                    && matches!(ident, Some(Identifier::Short) | Some(Identifier::Long))
                {
                    // Record flag's index
                    self.cur_idx.set(self.cur_idx.get() + 1);
                    debug!("Parser::react: cur_idx:={}", self.cur_idx.get());
                }
                self.start_custom_arg(matcher, arg, source);
                ok!(self.push_arg_values(arg, raw_vals, matcher));
                if cfg!(debug_assertions) && matcher.needs_more_vals(arg) {
                    debug!(
                        "Parser::react not enough values passed in, leaving it to the validator to complain",
                    );
                }
                Ok(ParseResult::ValuesDone)
            }
            ArgAction::SetTrue => {
                let raw_vals = if raw_vals.is_empty() {
                    vec![OsString::from("true")]
                } else {
                    raw_vals
                };

                if matcher.remove(arg.get_id())
                    && !(self.cmd.is_args_override_self() || arg.overrides.contains(arg.get_id()))
                {
                    return Err(ClapError::argument_conflict(
                        self.cmd,
                        arg.to_string(),
                        vec![arg.to_string()],
                        Usage::new(self.cmd).create_usage_with_title(&[]),
                    ));
                }
                self.start_custom_arg(matcher, arg, source);
                ok!(self.push_arg_values(arg, raw_vals, matcher));
                Ok(ParseResult::ValuesDone)
            }
            ArgAction::SetFalse => {
                let raw_vals = if raw_vals.is_empty() {
                    vec![OsString::from("false")]
                } else {
                    raw_vals
                };

                if matcher.remove(arg.get_id())
                    && !(self.cmd.is_args_override_self() || arg.overrides.contains(arg.get_id()))
                {
                    return Err(ClapError::argument_conflict(
                        self.cmd,
                        arg.to_string(),
                        vec![arg.to_string()],
                        Usage::new(self.cmd).create_usage_with_title(&[]),
                    ));
                }
                self.start_custom_arg(matcher, arg, source);
                ok!(self.push_arg_values(arg, raw_vals, matcher));
                Ok(ParseResult::ValuesDone)
            }
            ArgAction::Count => {
                let raw_vals = if raw_vals.is_empty() {
                    let existing_value = *matcher
                        .get_one::<crate::builder::CountType>(arg.get_id().as_str())
                        .unwrap_or(&0);
                    let next_value = existing_value.saturating_add(1);
                    vec![OsString::from(next_value.to_string())]
                } else {
                    raw_vals
                };

                matcher.remove(arg.get_id());
                self.start_custom_arg(matcher, arg, source);
                ok!(self.push_arg_values(arg, raw_vals, matcher));
                Ok(ParseResult::ValuesDone)
            }
            ArgAction::Help => {
                let use_long = match ident {
                    Some(Identifier::Long) => true,
                    Some(Identifier::Short) => false,
                    Some(Identifier::Index) => true,
                    None => true,
                };
                debug!("Help: use_long={}", use_long);
                Err(self.help_err(use_long))
            }
            ArgAction::Version => {
                let use_long = match ident {
                    Some(Identifier::Long) => true,
                    Some(Identifier::Short) => false,
                    Some(Identifier::Index) => true,
                    None => true,
                };
                debug!("Version: use_long={}", use_long);
                Err(self.version_err(use_long))
            }
        }
    }

Gets the value of a specific ArgAction::Count flag

Panic

If the argument’s action is not ArgAction::Count

Examples
let cmd = Command::new("mycmd")
    .arg(
        Arg::new("flag")
            .long("flag")
            .action(clap::ArgAction::Count)
    );

let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap();
assert_eq!(
    matches.get_count("flag"),
    2
);

Gets the value of a specific ArgAction::SetTrue or ArgAction::SetFalse flag

Panic

If the argument’s action is not ArgAction::SetTrue or ArgAction::SetFalse

Examples
let cmd = Command::new("mycmd")
    .arg(
        Arg::new("flag")
            .long("flag")
            .action(clap::ArgAction::SetTrue)
    );

let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap();
assert!(matches.contains_id("flag"));
assert_eq!(
    matches.get_flag("flag"),
    true
);

Iterate over values of a specific option or positional argument.

i.e. an argument that takes multiple values at runtime.

Returns an error if the wrong type was used.

Returns None if the option wasn’t present.

Panic

If the argument definition and access mismatch. To handle this case programmatically, see ArgMatches::try_get_many.

Examples
let m = Command::new("myprog")
    .arg(Arg::new("ports")
        .action(ArgAction::Append)
        .value_parser(value_parser!(usize))
        .short('p')
        .required(true))
    .get_matches_from(vec![
        "myprog", "-p", "22", "-p", "80", "-p", "2020"
    ]);
let vals: Vec<usize> = m.get_many("ports")
    .expect("`port`is required")
    .copied()
    .collect();
assert_eq!(vals, [22, 80, 2020]);
Available on crate feature unstable-grouped only.

Iterate over the values passed to each occurrence of an option.

Each item is itself an iterator containing the arguments passed to a single occurrence of the option.

If the option doesn’t support multiple occurrences, or there was only a single occurrence, the iterator will only contain a single item.

Returns None if the option wasn’t present.

Panics

If the argument definition and access mismatch. To handle this case programmatically, see ArgMatches::try_get_occurrences.

Examples
let m = Command::new("myprog")
    .arg(Arg::new("x")
        .short('x')
        .num_args(2)
        .action(ArgAction::Append)
        .value_parser(value_parser!(String)))
    .get_matches_from(vec![
        "myprog", "-x", "a", "b", "-x", "c", "d"]);
let vals: Vec<Vec<&String>> = m.get_occurrences("x").unwrap().map(Iterator::collect).collect();
assert_eq!(vals, [["a", "b"], ["c", "d"]]);

Iterate over the original argument values.

An OsStr on Unix-like systems is any series of bytes, regardless of whether or not they contain valid UTF-8. Since Strings in Rust are guaranteed to be valid UTF-8, a valid filename on a Unix system as an argument value may contain invalid UTF-8.

Returns None if the option wasn’t present.

Panic

If the argument definition and access mismatch. To handle this case programmatically, see ArgMatches::try_get_raw.

Examples
use std::path::PathBuf;

let m = Command::new("utf8")
   .arg(arg!(<arg> ... "some arg").value_parser(value_parser!(PathBuf)))
   .get_matches_from(vec![OsString::from("myprog"),
                               // "Hi"
                               OsString::from_vec(vec![b'H', b'i']),
                               // "{0xe9}!"
                               OsString::from_vec(vec![0xe9, b'!'])]);

let mut itr = m.get_raw("arg")
   .expect("`port`is required")
   .into_iter();
assert_eq!(itr.next(), Some(OsStr::new("Hi")));
assert_eq!(itr.next(), Some(OsStr::from_bytes(&[0xe9, b'!'])));
assert_eq!(itr.next(), None);
Available on crate feature unstable-grouped only.

Iterate over the original values for each occurrence of an option.

Similar to ArgMatches::get_occurrences but returns raw values.

An OsStr on Unix-like systems is any series of bytes, regardless of whether or not they contain valid UTF-8. Since Strings in Rust are guaranteed to be valid UTF-8, a valid filename on a Unix system as an argument value may contain invalid UTF-8.

Returns None if the option wasn’t present.

Panic

If the argument definition and access mismatch. To handle this case programmatically, see ArgMatches::try_get_raw_occurrences.

Examples
use std::path::PathBuf;

let m = Command::new("myprog")
   .arg(Arg::new("x")
       .short('x')
       .num_args(2)
       .action(ArgAction::Append)
       .value_parser(value_parser!(PathBuf)))
   .get_matches_from(vec![OsString::from("myprog"),
                           OsString::from("-x"),
                           OsString::from("a"), OsString::from("b"),
                           OsString::from("-x"),
                           OsString::from("c"),
                           // "{0xe9}!"
                           OsString::from_vec(vec![0xe9, b'!'])]);
let mut itr = m.get_raw_occurrences("x")
   .expect("`-x`is required")
   .map(Iterator::collect::<Vec<_>>);
assert_eq!(itr.next(), Some(vec![OsStr::new("a"), OsStr::new("b")]));
assert_eq!(itr.next(), Some(vec![OsStr::new("c"), OsStr::from_bytes(&[0xe9, b'!'])]));
assert_eq!(itr.next(), None);

Returns the value of a specific option or positional argument.

i.e. an argument that takes an additional value at runtime.

Returns an error if the wrong type was used. No item will have been removed.

Returns None if the option wasn’t present.

NOTE: This will always return Some(value) if default_value has been set. ArgMatches::value_source can be used to check if a value is present at runtime.

Panic

If the argument definition and access mismatch. To handle this case programmatically, see ArgMatches::try_remove_one.

Examples
let mut m = Command::new("myprog")
    .arg(Arg::new("file")
        .required(true)
        .action(ArgAction::Set))
    .get_matches_from(vec![
        "myprog", "file.txt",
    ]);
let vals: String = m.remove_one("file")
    .expect("`file`is required");
assert_eq!(vals, "file.txt");

Return values of a specific option or positional argument.

i.e. an argument that takes multiple values at runtime.

Returns an error if the wrong type was used. No item will have been removed.

Returns None if the option wasn’t present.

Panic

If the argument definition and access mismatch. To handle this case programmatically, see ArgMatches::try_remove_many.

Examples
let mut m = Command::new("myprog")
    .arg(Arg::new("file")
        .action(ArgAction::Append)
        .num_args(1..)
        .required(true))
    .get_matches_from(vec![
        "myprog", "file1.txt", "file2.txt", "file3.txt", "file4.txt",
    ]);
let vals: Vec<String> = m.remove_many("file")
    .expect("`file`is required")
    .collect();
assert_eq!(vals, ["file1.txt", "file2.txt", "file3.txt", "file4.txt"]);
Available on crate feature unstable-grouped only.

Return values for each occurrence of an option.

Each item is itself an iterator containing the arguments passed to a single occurrence of the option.

If the option doesn’t support multiple occurrences, or there was only a single occurrence, the iterator will only contain a single item.

Returns None if the option wasn’t present.

Panic

If the argument definition and access mismatch. To handle this case programmatically, see ArgMatches::try_remove_occurrences.

Examples
let mut m = Command::new("myprog")
    .arg(Arg::new("x")
        .short('x')
        .num_args(2)
        .action(ArgAction::Append)
        .value_parser(value_parser!(String)))
    .get_matches_from(vec![
        "myprog", "-x", "a", "b", "-x", "c", "d"]);
let vals: Vec<Vec<String>> = m.remove_occurrences("x").unwrap().map(Iterator::collect).collect();
assert_eq!(vals, [["a", "b"], ["c", "d"]]);

Check if values are present for the argument or group id

NOTE: This will always return true if default_value has been set. ArgMatches::value_source can be used to check if a value is present at runtime.

Panics

If id is is not a valid argument or group name. To handle this case programmatically, see ArgMatches::try_contains_id.

Examples
let m = Command::new("myprog")
    .arg(Arg::new("debug")
        .short('d')
        .action(ArgAction::SetTrue))
    .get_matches_from(vec![
        "myprog", "-d"
    ]);

assert!(m.contains_id("debug"));

Iterate over Arg and ArgGroup Ids via ArgMatches::ids.

Examples

let m = Command::new("myprog")
    .arg(arg!(--color <when>)
        .value_parser(["auto", "always", "never"]))
    .arg(arg!(--config <path>)
        .value_parser(value_parser!(std::path::PathBuf)))
    .get_matches_from(["myprog", "--config=config.toml", "--color=auto"]);
assert_eq!(m.ids().len(), 2);
assert_eq!(
    m.ids()
        .map(|id| id.as_str())
        .collect::<Vec<_>>(),
    ["config", "color"]
);

Check if any args were present on the command line

Examples
let mut cmd = Command::new("myapp")
    .arg(Arg::new("output")
        .action(ArgAction::Set));

let m = cmd
    .try_get_matches_from_mut(vec!["myapp", "something"])
    .unwrap();
assert!(m.args_present());

let m = cmd
    .try_get_matches_from_mut(vec!["myapp"])
    .unwrap();
assert!(! m.args_present());
👎Deprecated since 4.1.0: Use get_occurrences or remove_occurrences instead
Available on crate feature unstable-grouped only.

Get an Iterator over groups of values of a specific option.

specifically grouped by the occurrences of the options.

Each group is a Vec<&str> containing the arguments passed to a single occurrence of the option.

If the option doesn’t support multiple occurrences, or there was only a single occurrence, the iterator will only contain a single item.

Returns None if the option wasn’t present.

Panics

If the value is invalid UTF-8.

If id is not a valid argument or group id.

Examples
let m = Command::new("myprog")
    .arg(Arg::new("exec")
        .short('x')
        .num_args(1..)
        .action(ArgAction::Append)
        .value_terminator(";"))
    .get_matches_from(vec![
        "myprog", "-x", "echo", "hi", ";", "-x", "echo", "bye"]);
let vals: Vec<Vec<&str>> = m.grouped_values_of("exec").unwrap().collect();
assert_eq!(vals, [["echo", "hi"], ["echo", "bye"]]);

Report where argument value came from

Panics

If id is is not a valid argument or group id.

Examples
let m = Command::new("myprog")
    .arg(Arg::new("debug")
        .short('d')
        .action(ArgAction::SetTrue))
    .get_matches_from(vec![
        "myprog", "-d"
    ]);

assert_eq!(m.value_source("debug"), Some(ValueSource::CommandLine));

The first index of that an argument showed up.

Indices are similar to argv indices, but are not exactly 1:1.

For flags (i.e. those arguments which don’t have an associated value), indices refer to occurrence of the switch, such as -f, or --flag. However, for options the indices refer to the values -o val would therefore not represent two distinct indices, only the index for val would be recorded. This is by design.

Besides the flag/option discrepancy, the primary difference between an argv index and clap index, is that clap continues counting once all arguments have properly separated, whereas an argv index does not.

The examples should clear this up.

NOTE: If an argument is allowed multiple times, this method will only give the first index. See ArgMatches::indices_of.

Panics

If id is is not a valid argument or group id.

Examples

The argv indices are listed in the comments below. See how they correspond to the clap indices. Note that if it’s not listed in a clap index, this is because it’s not saved in in an ArgMatches struct for querying.

let m = Command::new("myapp")
    .arg(Arg::new("flag")
        .short('f')
        .action(ArgAction::SetTrue))
    .arg(Arg::new("option")
        .short('o')
        .action(ArgAction::Set))
    .get_matches_from(vec!["myapp", "-f", "-o", "val"]);
           // ARGV indices: ^0       ^1    ^2    ^3
           // clap indices:          ^1          ^3

assert_eq!(m.index_of("flag"), Some(1));
assert_eq!(m.index_of("option"), Some(3));

Now notice, if we use one of the other styles of options:

let m = Command::new("myapp")
    .arg(Arg::new("flag")
        .short('f')
        .action(ArgAction::SetTrue))
    .arg(Arg::new("option")
        .short('o')
        .action(ArgAction::Set))
    .get_matches_from(vec!["myapp", "-f", "-o=val"]);
           // ARGV indices: ^0       ^1    ^2
           // clap indices:          ^1       ^3

assert_eq!(m.index_of("flag"), Some(1));
assert_eq!(m.index_of("option"), Some(3));

Things become much more complicated, or clear if we look at a more complex combination of flags. Let’s also throw in the final option style for good measure.

let m = Command::new("myapp")
    .arg(Arg::new("flag")
        .short('f')
        .action(ArgAction::SetTrue))
    .arg(Arg::new("flag2")
        .short('F')
        .action(ArgAction::SetTrue))
    .arg(Arg::new("flag3")
        .short('z')
        .action(ArgAction::SetTrue))
    .arg(Arg::new("option")
        .short('o')
        .action(ArgAction::Set))
    .get_matches_from(vec!["myapp", "-fzF", "-oval"]);
           // ARGV indices: ^0      ^1       ^2
           // clap indices:         ^1,2,3    ^5
           //
           // clap sees the above as 'myapp -f -z -F -o val'
           //                         ^0    ^1 ^2 ^3 ^4 ^5
assert_eq!(m.index_of("flag"), Some(1));
assert_eq!(m.index_of("flag2"), Some(3));
assert_eq!(m.index_of("flag3"), Some(2));
assert_eq!(m.index_of("option"), Some(5));

One final combination of flags/options to see how they combine:

let m = Command::new("myapp")
    .arg(Arg::new("flag")
        .short('f')
        .action(ArgAction::SetTrue))
    .arg(Arg::new("flag2")
        .short('F')
        .action(ArgAction::SetTrue))
    .arg(Arg::new("flag3")
        .short('z')
        .action(ArgAction::SetTrue))
    .arg(Arg::new("option")
        .short('o')
        .action(ArgAction::Set))
    .get_matches_from(vec!["myapp", "-fzFoval"]);
           // ARGV indices: ^0       ^1
           // clap indices:          ^1,2,3^5
           //
           // clap sees the above as 'myapp -f -z -F -o val'
           //                         ^0    ^1 ^2 ^3 ^4 ^5
assert_eq!(m.index_of("flag"), Some(1));
assert_eq!(m.index_of("flag2"), Some(3));
assert_eq!(m.index_of("flag3"), Some(2));
assert_eq!(m.index_of("option"), Some(5));

The last part to mention is when values are sent in multiple groups with a delimiter.

let m = Command::new("myapp")
    .arg(Arg::new("option")
        .short('o')
        .value_delimiter(',')
        .num_args(1..))
    .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
           // ARGV indices: ^0       ^1
           // clap indices:             ^2   ^3   ^4
           //
           // clap sees the above as 'myapp -o val1 val2 val3'
           //                         ^0    ^1 ^2   ^3   ^4
assert_eq!(m.index_of("option"), Some(2));
assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 3, 4]);

All indices an argument appeared at when parsing.

Indices are similar to argv indices, but are not exactly 1:1.

For flags (i.e. those arguments which don’t have an associated value), indices refer to occurrence of the switch, such as -f, or --flag. However, for options the indices refer to the values -o val would therefore not represent two distinct indices, only the index for val would be recorded. This is by design.

NOTE: For more information about how clap indices compared to argv indices, see ArgMatches::index_of

Panics

If id is is not a valid argument or group id.

Examples
let m = Command::new("myapp")
    .arg(Arg::new("option")
        .short('o')
        .value_delimiter(','))
    .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
           // ARGV indices: ^0       ^1
           // clap indices:             ^2   ^3   ^4
           //
           // clap sees the above as 'myapp -o val1 val2 val3'
           //                         ^0    ^1 ^2   ^3   ^4
assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 3, 4]);

Another quick example is when flags and options are used together

let m = Command::new("myapp")
    .arg(Arg::new("option")
        .short('o')
        .action(ArgAction::Set)
        .action(ArgAction::Append))
    .arg(Arg::new("flag")
        .short('f')
        .action(ArgAction::Count))
    .get_matches_from(vec!["myapp", "-o", "val1", "-f", "-o", "val2", "-f"]);
           // ARGV indices: ^0       ^1    ^2      ^3    ^4    ^5      ^6
           // clap indices:                ^2      ^3          ^5      ^6

assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 5]);
assert_eq!(m.indices_of("flag").unwrap().collect::<Vec<_>>(), &[6]);

One final example, which is an odd case; if we don’t use value delimiter as we did with the first example above instead of val1, val2 and val3 all being distinc values, they would all be a single value of val1,val2,val3, in which case they’d only receive a single index.

let m = Command::new("myapp")
    .arg(Arg::new("option")
        .short('o')
        .action(ArgAction::Set)
        .num_args(1..))
    .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
           // ARGV indices: ^0       ^1
           // clap indices:             ^2
           //
           // clap sees the above as 'myapp -o "val1,val2,val3"'
           //                         ^0    ^1  ^2
assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2]);

The name and ArgMatches of the current subcommand.

Subcommand values are put in a child ArgMatches

Returns None if the subcommand wasn’t present at runtime,

Examples
 let app_m = Command::new("git")
     .subcommand(Command::new("clone"))
     .subcommand(Command::new("push"))
     .subcommand(Command::new("commit"))
     .get_matches();

match app_m.subcommand() {
    Some(("clone",  sub_m)) => {}, // clone was used
    Some(("push",   sub_m)) => {}, // push was used
    Some(("commit", sub_m)) => {}, // commit was used
    _                       => {}, // Either no subcommand or one not tested for...
}

Another useful scenario is when you want to support third party, or external, subcommands. In these cases you can’t know the subcommand name ahead of time, so use a variable instead with pattern matching!

// Assume there is an external subcommand named "subcmd"
let app_m = Command::new("myprog")
    .allow_external_subcommands(true)
    .get_matches_from(vec![
        "myprog", "subcmd", "--option", "value", "-fff", "--flag"
    ]);

// All trailing arguments will be stored under the subcommand's sub-matches using an empty
// string argument name
match app_m.subcommand() {
    Some((external, sub_m)) => {
         let ext_args: Vec<&OsStr> = sub_m.get_many::<OsString>("")
            .unwrap().map(|s| s.as_os_str()).collect();
         assert_eq!(external, "subcmd");
         assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]);
    },
    _ => {},
}
Examples found in repository?
src/builder/command.rs (line 3774)
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
    fn get_used_global_args(&self, matches: &ArgMatches, global_arg_vec: &mut Vec<Id>) {
        global_arg_vec.extend(
            self.args
                .args()
                .filter(|a| a.is_global_set())
                .map(|ga| ga.id.clone()),
        );
        if let Some((id, matches)) = matches.subcommand() {
            if let Some(used_sub) = self.find_subcommand(id) {
                used_sub.get_used_global_args(matches, global_arg_vec);
            }
        }
    }

Return the name and ArgMatches of the current subcommand.

Subcommand values are put in a child ArgMatches

Returns None if the subcommand wasn’t present at runtime,

Examples
 let mut app_m = Command::new("git")
     .subcommand(Command::new("clone"))
     .subcommand(Command::new("push"))
     .subcommand(Command::new("commit"))
     .subcommand_required(true)
     .get_matches();

let (name, sub_m) = app_m.remove_subcommand().expect("required");
match (name.as_str(), sub_m) {
    ("clone",  sub_m) => {}, // clone was used
    ("push",   sub_m) => {}, // push was used
    ("commit", sub_m) => {}, // commit was used
    (name, _)         => unimplemented!("{}", name),
}

Another useful scenario is when you want to support third party, or external, subcommands. In these cases you can’t know the subcommand name ahead of time, so use a variable instead with pattern matching!

// Assume there is an external subcommand named "subcmd"
let mut app_m = Command::new("myprog")
    .allow_external_subcommands(true)
    .get_matches_from(vec![
        "myprog", "subcmd", "--option", "value", "-fff", "--flag"
    ]);

// All trailing arguments will be stored under the subcommand's sub-matches using an empty
// string argument name
match app_m.remove_subcommand() {
    Some((external, mut sub_m)) => {
         let ext_args: Vec<OsString> = sub_m.remove_many("")
            .expect("`file`is required")
            .collect();
         assert_eq!(external, "subcmd");
         assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]);
    },
    _ => {},
}

The ArgMatches for the current subcommand.

Subcommand values are put in a child ArgMatches

Returns None if the subcommand wasn’t present at runtime,

Panics

If id is is not a valid subcommand.

Examples
let app_m = Command::new("myprog")
    .arg(Arg::new("debug")
        .short('d')
        .action(ArgAction::SetTrue)
    )
    .subcommand(Command::new("test")
        .arg(Arg::new("opt")
            .long("option")
            .action(ArgAction::Set)))
    .get_matches_from(vec![
        "myprog", "-d", "test", "--option", "val"
    ]);

// Both parent commands, and child subcommands can have arguments present at the same times
assert!(*app_m.get_one::<bool>("debug").expect("defaulted by clap"));

// Get the subcommand's ArgMatches instance
if let Some(sub_m) = app_m.subcommand_matches("test") {
    // Use the struct like normal
    assert_eq!(sub_m.get_one::<String>("opt").map(|s| s.as_str()), Some("val"));
}

The name of the current subcommand.

Returns None if the subcommand wasn’t present at runtime,

Examples
 let app_m = Command::new("git")
     .subcommand(Command::new("clone"))
     .subcommand(Command::new("push"))
     .subcommand(Command::new("commit"))
     .get_matches();

match app_m.subcommand_name() {
    Some("clone")  => {}, // clone was used
    Some("push")   => {}, // push was used
    Some("commit") => {}, // commit was used
    _              => {}, // Either no subcommand or one not tested for...
}
Examples found in repository?
src/parser/arg_matcher.rs (line 129)
128
129
130
    pub(crate) fn subcommand_name(&self) -> Option<&str> {
        self.matches.subcommand_name()
    }

Non-panicking version of ArgMatches::get_one

Examples found in repository?
src/parser/matches/arg_matches.rs (line 113)
112
113
114
    pub fn get_one<T: Any + Clone + Send + Sync + 'static>(&self, id: &str) -> Option<&T> {
        MatchesError::unwrap(id, self.try_get_one(id))
    }

Non-panicking version of ArgMatches::get_many

Examples found in repository?
src/parser/matches/arg_matches.rs (line 216)
212
213
214
215
216
217
    pub fn get_many<T: Any + Clone + Send + Sync + 'static>(
        &self,
        id: &str,
    ) -> Option<ValuesRef<T>> {
        MatchesError::unwrap(id, self.try_get_many(id))
    }
Available on crate feature unstable-grouped only.

Non-panicking version of ArgMatches::get_occurrences

Examples found in repository?
src/parser/matches/arg_matches.rs (line 254)
250
251
252
253
254
255
    pub fn get_occurrences<T: Any + Clone + Send + Sync + 'static>(
        &self,
        id: &str,
    ) -> Option<OccurrencesRef<T>> {
        MatchesError::unwrap(id, self.try_get_occurrences(id))
    }

Non-panicking version of ArgMatches::get_raw

Examples found in repository?
src/parser/matches/arg_matches.rs (line 300)
299
300
301
    pub fn get_raw(&self, id: &str) -> Option<RawValues<'_>> {
        MatchesError::unwrap(id, self.try_get_raw(id))
    }
Available on crate feature unstable-grouped only.

Non-panicking version of ArgMatches::get_raw_occurrences

Examples found in repository?
src/parser/matches/arg_matches.rs (line 354)
353
354
355
    pub fn get_raw_occurrences(&self, id: &str) -> Option<RawOccurrences<'_>> {
        MatchesError::unwrap(id, self.try_get_raw_occurrences(id))
    }

Non-panicking version of ArgMatches::remove_one

Examples found in repository?
src/parser/matches/arg_matches.rs (line 392)
391
392
393
    pub fn remove_one<T: Any + Clone + Send + Sync + 'static>(&mut self, id: &str) -> Option<T> {
        MatchesError::unwrap(id, self.try_remove_one(id))
    }

Non-panicking version of ArgMatches::remove_many

Examples found in repository?
src/parser/matches/arg_matches.rs (line 430)
426
427
428
429
430
431
    pub fn remove_many<T: Any + Clone + Send + Sync + 'static>(
        &mut self,
        id: &str,
    ) -> Option<Values<T>> {
        MatchesError::unwrap(id, self.try_remove_many(id))
    }
Available on crate feature unstable-grouped only.

Non-panicking version of ArgMatches::remove_occurrences

Examples found in repository?
src/parser/matches/arg_matches.rs (line 469)
465
466
467
468
469
470
    pub fn remove_occurrences<T: Any + Clone + Send + Sync + 'static>(
        &mut self,
        id: &str,
    ) -> Option<Occurrences<T>> {
        MatchesError::unwrap(id, self.try_remove_occurrences(id))
    }

Non-panicking version of ArgMatches::contains_id

Examples found in repository?
src/parser/matches/arg_matches.rs (line 499)
498
499
500
    pub fn contains_id(&self, id: &str) -> bool {
        MatchesError::unwrap(id, self.try_contains_id(id))
    }

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
Returns the “default value” for a type. Read more
This method tests for self and other values to be equal, and is used by ==.
This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.