Skip to main content

clap_builder/parser/
parser.rs

1// Std
2use std::{
3    cell::Cell,
4    ffi::{OsStr, OsString},
5};
6
7use clap_lex::OsStrExt as _;
8
9// Internal
10use crate::ArgAction;
11use crate::INTERNAL_ERROR_MSG;
12use crate::builder::{Arg, Command};
13use crate::error::Error as ClapError;
14use crate::error::Result as ClapResult;
15use crate::mkeymap::KeyType;
16use crate::output::Usage;
17use crate::parser::features::suggestions;
18use crate::parser::{ArgMatcher, SubCommand};
19use crate::parser::{Validator, ValueSource};
20use crate::util::AnyValue;
21use crate::util::Id;
22
23pub(crate) struct Parser<'cmd> {
24    cmd: &'cmd mut Command,
25    cur_idx: Cell<usize>,
26    /// Index of the previous flag subcommand in a group of flags.
27    flag_subcmd_at: Option<usize>,
28    /// Counter indicating the number of items to skip
29    /// when revisiting the group of flags which includes the flag subcommand.
30    flag_subcmd_skip: usize,
31}
32
33// Initializing Methods
34impl<'cmd> Parser<'cmd> {
35    pub(crate) fn new(cmd: &'cmd mut Command) -> Self {
36        Parser {
37            cmd,
38            cur_idx: Cell::new(0),
39            flag_subcmd_at: None,
40            flag_subcmd_skip: 0,
41        }
42    }
43}
44
45// Parsing Methods
46impl<'cmd> Parser<'cmd> {
47    // The actual parsing function
48    #[allow(clippy::cognitive_complexity)]
49    pub(crate) fn get_matches_with(
50        &mut self,
51        matcher: &mut ArgMatcher,
52        raw_args: &mut clap_lex::RawArgs,
53        args_cursor: clap_lex::ArgCursor,
54    ) -> ClapResult<()> {
55        debug!("Parser::get_matches_with");
56
57        match self.parse(matcher, raw_args,
            args_cursor).inspect_err(|_err|
            {
                if self.cmd.is_ignore_errors_set() {
                    let _ = self.add_defaults(matcher);
                }
            }) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
};ok!(self
58            .parse(matcher, raw_args, args_cursor)
59            .inspect_err(|_err| {
60                if self.cmd.is_ignore_errors_set() {
61                    #[cfg(feature = "env")]
62                    let _ = self.add_env(matcher);
63                    let _ = self.add_defaults(matcher);
64                }
65            }));
66        match self.resolve_pending(matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
};ok!(self.resolve_pending(matcher));
67
68        #[cfg(feature = "env")]
69        ok!(self.add_env(matcher));
70        match self.add_defaults(matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
};ok!(self.add_defaults(matcher));
71
72        Validator::new(self.cmd).validate(matcher)
73    }
74
75    // The actual parsing function
76    #[allow(clippy::cognitive_complexity)]
77    pub(crate) fn parse(
78        &mut self,
79        matcher: &mut ArgMatcher,
80        raw_args: &mut clap_lex::RawArgs,
81        mut args_cursor: clap_lex::ArgCursor,
82    ) -> ClapResult<()> {
83        debug!("Parser::parse");
84        // Verify all positional assertions pass
85
86        let mut subcmd_name: Option<String> = None;
87        let mut keep_state = false;
88        let mut parse_state = ParseState::ValuesDone;
89        let mut pos_counter = 1;
90
91        // Already met any valid arg(then we shouldn't expect subcommands after it).
92        let mut valid_arg_found = false;
93        // If the user already passed '--'. Meaning only positional args follow.
94        let mut trailing_values = false;
95
96        // Count of positional args
97        let positional_count = self
98            .cmd
99            .get_keymap()
100            .keys()
101            .filter(|x| x.is_position())
102            .count();
103        // If any arg sets .last(true)
104        let contains_last = self.cmd.get_arguments().any(|x| x.is_last_set());
105
106        while let Some(arg_os) = raw_args.next(&mut args_cursor) {
107            debug!(
108                "Parser::get_matches_with: Begin parsing '{:?}'",
109                arg_os.to_value_os(),
110            );
111
112            // Has the user already passed '--'? Meaning only positional args follow
113            if !trailing_values {
114                if self.cmd.is_subcommand_precedence_over_arg_set()
115                    || !#[allow(non_exhaustive_omitted_patterns)] match parse_state {
    ParseState::Opt(_) | ParseState::Pos(_) => true,
    _ => false,
}matches!(parse_state, ParseState::Opt(_) | ParseState::Pos(_))
116                {
117                    // Does the arg match a subcommand name, or any of its aliases (if defined)
118                    let sc_name = self.possible_subcommand(arg_os.to_value(), valid_arg_found);
119                    debug!("Parser::get_matches_with: sc={sc_name:?}");
120                    if let Some(sc_name) = sc_name {
121                        if sc_name == "help" && !self.cmd.is_disable_help_subcommand_set() {
122                            match self.parse_help_subcommand(raw_args.remaining(&mut args_cursor)) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
};ok!(self.parse_help_subcommand(raw_args.remaining(&mut args_cursor)));
123                            {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("`parse_help_subcommand` always errors")));
};unreachable!("`parse_help_subcommand` always errors");
124                        } else {
125                            subcmd_name = Some(sc_name.to_owned());
126                        }
127                        break;
128                    }
129                }
130
131                if arg_os.is_escape() {
132                    if #[allow(non_exhaustive_omitted_patterns)] match &parse_state {
    ParseState::Opt(opt) | ParseState::Pos(opt) if
        self.cmd[opt].is_allow_hyphen_values_set() => true,
    _ => false,
}matches!(&parse_state, ParseState::Opt(opt) | ParseState::Pos(opt) if
133                        self.cmd[opt].is_allow_hyphen_values_set())
134                    {
135                        // ParseResult::MaybeHyphenValue, do nothing
136                    } else {
137                        debug!("Parser::get_matches_with: setting TrailingVals=true");
138                        if self.cmd.get_keymap().get(&pos_counter).is_some_and(|arg| {
139                            self.check_terminator(arg, arg_os.to_value_os()).is_some()
140                        }) {
141                            // count as both an escape and terminator
142                            pos_counter += 1;
143                        }
144                        trailing_values = true;
145                        matcher.start_trailing();
146                        continue;
147                    }
148                } else if let Some((long_arg, long_value)) = arg_os.to_long() {
149                    let parse_result = match self.parse_long_arg(matcher, long_arg, long_value, &parse_state,
        pos_counter, &mut valid_arg_found) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
}ok!(self.parse_long_arg(
150                        matcher,
151                        long_arg,
152                        long_value,
153                        &parse_state,
154                        pos_counter,
155                        &mut valid_arg_found,
156                    ));
157                    debug!("Parser::get_matches_with: After parse_long_arg {parse_result:?}");
158                    match parse_result {
159                        ParseResult::NoArg => {
160                            {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("`to_long` always has the flag specified")));
}unreachable!("`to_long` always has the flag specified")
161                        }
162                        ParseResult::ValuesDone => {
163                            parse_state = ParseState::ValuesDone;
164                            continue;
165                        }
166                        ParseResult::Opt(id) => {
167                            parse_state = ParseState::Opt(id);
168                            continue;
169                        }
170                        ParseResult::FlagSubCommand(name) => {
171                            debug!(
172                                "Parser::get_matches_with: FlagSubCommand found in long arg {:?}",
173                                &name
174                            );
175                            subcmd_name = Some(name);
176                            break;
177                        }
178                        ParseResult::EqualsNotProvided { arg } => {
179                            let _ = self.resolve_pending(matcher);
180                            return Err(ClapError::no_equals(
181                                self.cmd,
182                                arg,
183                                Usage::new(self.cmd).create_usage_with_title(&[]),
184                            ));
185                        }
186                        ParseResult::NoMatchingArg { arg } => {
187                            let _ = self.resolve_pending(matcher);
188                            let remaining_args: Vec<_> =
189                                raw_args.remaining(&mut args_cursor).collect();
190                            return Err(self.did_you_mean_error(
191                                &arg,
192                                matcher,
193                                &remaining_args,
194                                trailing_values,
195                            ));
196                        }
197                        ParseResult::UnneededAttachedValue { rest, used, arg } => {
198                            let _ = self.resolve_pending(matcher);
199                            return Err(ClapError::too_many_values(
200                                self.cmd,
201                                rest,
202                                arg,
203                                Usage::new(self.cmd).create_usage_with_title(&used),
204                            ));
205                        }
206                        ParseResult::MaybeHyphenValue => {
207                            // Maybe a hyphen value, do nothing.
208                        }
209                        ParseResult::AttachedValueNotConsumed => {
210                            ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
211                        }
212                    }
213                } else if let Some(short_arg) = arg_os.to_short() {
214                    // Arg looks like a short flag, and not a possible number
215
216                    // Try to parse short args like normal, if allow_hyphen_values or
217                    // AllowNegativeNumbers is set, parse_short_arg will *not* throw
218                    // an error, and instead return Ok(None)
219                    let parse_result = match self.parse_short_arg(matcher, short_arg, &parse_state, pos_counter,
        &mut valid_arg_found) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
}ok!(self.parse_short_arg(
220                        matcher,
221                        short_arg,
222                        &parse_state,
223                        pos_counter,
224                        &mut valid_arg_found,
225                    ));
226                    // If it's None, we then check if one of those two AppSettings was set
227                    debug!("Parser::get_matches_with: After parse_short_arg {parse_result:?}");
228                    match parse_result {
229                        ParseResult::NoArg => {
230                            // Is a single dash `-`, try positional.
231                        }
232                        ParseResult::ValuesDone => {
233                            parse_state = ParseState::ValuesDone;
234                            continue;
235                        }
236                        ParseResult::Opt(id) => {
237                            parse_state = ParseState::Opt(id);
238                            continue;
239                        }
240                        ParseResult::FlagSubCommand(name) => {
241                            // If there are more short flags to be processed, we should keep the state, and later
242                            // revisit the current group of short flags skipping the subcommand.
243                            keep_state = self
244                                .flag_subcmd_at
245                                .map(|at| {
246                                    raw_args
247                                        .seek(&mut args_cursor, clap_lex::SeekFrom::Current(-1));
248                                    // Since we are now saving the current state, the number of flags to skip during state recovery should
249                                    // be the current index (`cur_idx`) minus ONE UNIT TO THE LEFT of the starting position.
250                                    self.flag_subcmd_skip = self.cur_idx.get() - at + 1;
251                                })
252                                .is_some();
253
254                            debug!(
255                                "Parser::get_matches_with:FlagSubCommandShort: subcmd_name={}, keep_state={}, flag_subcmd_skip={}",
256                                name, keep_state, self.flag_subcmd_skip
257                            );
258
259                            subcmd_name = Some(name);
260                            break;
261                        }
262                        ParseResult::EqualsNotProvided { arg } => {
263                            let _ = self.resolve_pending(matcher);
264                            return Err(ClapError::no_equals(
265                                self.cmd,
266                                arg,
267                                Usage::new(self.cmd).create_usage_with_title(&[]),
268                            ));
269                        }
270                        ParseResult::NoMatchingArg { arg } => {
271                            let _ = self.resolve_pending(matcher);
272                            // We already know it looks like a flag
273                            let suggested_trailing_arg =
274                                !trailing_values && self.cmd.has_positionals();
275                            return Err(ClapError::unknown_argument(
276                                self.cmd,
277                                arg,
278                                None,
279                                suggested_trailing_arg,
280                                Usage::new(self.cmd).create_usage_with_title(&[]),
281                            ));
282                        }
283                        ParseResult::MaybeHyphenValue => {
284                            // Maybe a hyphen value, do nothing.
285                        }
286                        ParseResult::UnneededAttachedValue { .. }
287                        | ParseResult::AttachedValueNotConsumed => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
288                    }
289                }
290
291                if let ParseState::Opt(id) = &parse_state {
292                    // Assume this is a value of a previous arg.
293
294                    // get the option so we can check the settings
295                    let arg = &self.cmd[id];
296                    let parse_result = if let Some(parse_result) =
297                        self.check_terminator(arg, arg_os.to_value_os())
298                    {
299                        parse_result
300                    } else {
301                        let trailing_values = false;
302                        let arg_values = matcher.pending_values_mut(id, None, trailing_values);
303                        arg_values.push(arg_os.to_value_os().to_owned());
304                        if matcher.needs_more_vals(arg) {
305                            ParseResult::Opt(arg.get_id().clone())
306                        } else {
307                            ParseResult::ValuesDone
308                        }
309                    };
310                    parse_state = match parse_result {
311                        ParseResult::Opt(id) => ParseState::Opt(id),
312                        ParseResult::ValuesDone => ParseState::ValuesDone,
313                        _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
314                    };
315                    // get the next value from the iterator
316                    continue;
317                }
318            }
319
320            // Correct pos_counter.
321            pos_counter = {
322                let is_second_to_last = pos_counter + 1 == positional_count;
323
324                // The last positional argument, or second to last positional
325                // argument may be set to .multiple_values(true) or `.multiple_occurrences(true)`
326                let low_index_mults = is_second_to_last
327                    && self.cmd.get_positionals().any(|a| {
328                        a.is_multiple() && (positional_count != a.get_index().unwrap_or(0))
329                    })
330                    && self
331                        .cmd
332                        .get_positionals()
333                        .last()
334                        .map(|p_name| !p_name.is_last_set())
335                        .unwrap_or_default();
336
337                let is_terminated = self
338                    .cmd
339                    .get_keymap()
340                    .get(&pos_counter)
341                    .map(|a| a.get_value_terminator().is_some())
342                    .unwrap_or_default();
343
344                let missing_pos = self.cmd.is_allow_missing_positional_set()
345                    && is_second_to_last
346                    && !trailing_values;
347
348                debug!("Parser::get_matches_with: Positional counter...{pos_counter}");
349                debug!("Parser::get_matches_with: Low index multiples...{low_index_mults:?}");
350
351                if (low_index_mults || missing_pos) && !is_terminated {
352                    let skip_current = if let Some(n) = raw_args.peek(&args_cursor) {
353                        if let Some(arg) = self
354                            .cmd
355                            .get_positionals()
356                            .find(|a| a.get_index() == Some(pos_counter))
357                        {
358                            // If next value looks like a new_arg or it's a
359                            // subcommand, skip positional argument under current
360                            // pos_counter(which means current value cannot be a
361                            // positional argument with a value next to it), assume
362                            // current value matches the next arg.
363                            self.is_new_arg(&n, arg)
364                                || self
365                                    .possible_subcommand(n.to_value(), valid_arg_found)
366                                    .is_some()
367                        } else {
368                            true
369                        }
370                    } else {
371                        true
372                    };
373
374                    if skip_current {
375                        debug!("Parser::get_matches_with: Bumping the positional counter...");
376                        pos_counter + 1
377                    } else {
378                        pos_counter
379                    }
380                } else if trailing_values
381                    && (self.cmd.is_allow_missing_positional_set() || contains_last)
382                {
383                    // Came to -- and one positional has .last(true) set, so we go immediately
384                    // to the last (highest index) positional
385                    debug!("Parser::get_matches_with: .last(true) and --, setting last pos");
386                    positional_count
387                } else {
388                    pos_counter
389                }
390            };
391
392            if let Some(arg) = self.cmd.get_keymap().get(&pos_counter) {
393                if arg.is_last_set() && !trailing_values {
394                    let _ = self.resolve_pending(matcher);
395                    // Its already considered a positional, we don't need to suggest turning it
396                    // into one
397                    let suggested_trailing_arg = false;
398                    return Err(ClapError::unknown_argument(
399                        self.cmd,
400                        arg_os.display().to_string(),
401                        None,
402                        suggested_trailing_arg,
403                        Usage::new(self.cmd).create_usage_with_title(&[]),
404                    ));
405                }
406
407                if arg.is_trailing_var_arg_set() {
408                    trailing_values = true;
409                }
410
411                if matcher.pending_arg_id() != Some(arg.get_id()) || !arg.is_multiple_values_set() {
412                    match self.resolve_pending(matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
};ok!(self.resolve_pending(matcher));
413                }
414                parse_state =
415                    if let Some(parse_result) = self.check_terminator(arg, arg_os.to_value_os()) {
416                        if true {
    match (&parse_result, &ParseResult::ValuesDone) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    };
};debug_assert_eq!(parse_result, ParseResult::ValuesDone);
417                        pos_counter += 1;
418                        ParseState::ValuesDone
419                    } else {
420                        let arg_values = matcher.pending_values_mut(
421                            arg.get_id(),
422                            Some(Identifier::Index),
423                            trailing_values,
424                        );
425                        arg_values.push(arg_os.to_value_os().to_owned());
426
427                        // Only increment the positional counter if it doesn't allow multiples
428                        if !arg.is_multiple() {
429                            pos_counter += 1;
430                            ParseState::ValuesDone
431                        } else {
432                            ParseState::Pos(arg.get_id().clone())
433                        }
434                    };
435                valid_arg_found = true;
436            } else if let Some(external_parser) =
437                self.cmd.get_external_subcommand_value_parser().cloned()
438            {
439                // Get external subcommand name
440                let sc_name = match arg_os.to_value() {
441                    Ok(s) => s.to_owned(),
442                    Err(_) => {
443                        let _ = self.resolve_pending(matcher);
444                        return Err(ClapError::invalid_utf8(
445                            self.cmd,
446                            Usage::new(self.cmd).create_usage_with_title(&[]),
447                        ));
448                    }
449                };
450
451                // Collect the external subcommand args
452                let mut sc_m = ArgMatcher::new(self.cmd);
453                sc_m.start_occurrence_of_external(self.cmd);
454
455                for raw_val in raw_args.remaining(&mut args_cursor) {
456                    let val = match external_parser.parse_ref(self.cmd, None, raw_val,
        ValueSource::CommandLine) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
}ok!(external_parser.parse_ref(
457                        self.cmd,
458                        None,
459                        raw_val,
460                        ValueSource::CommandLine
461                    ));
462                    let external_id = Id::from_static_ref(Id::EXTERNAL);
463                    sc_m.add_val_to(&external_id, val, raw_val.to_os_string());
464                }
465
466                matcher.subcommand(SubCommand {
467                    name: sc_name,
468                    matches: sc_m.into_inner(),
469                });
470
471                return Ok(());
472            } else {
473                // Start error processing
474                let _ = self.resolve_pending(matcher);
475                return Err(self.match_arg_error(
476                    &arg_os,
477                    valid_arg_found,
478                    trailing_values,
479                    matcher,
480                ));
481            }
482        }
483
484        if let Some(ref pos_sc_name) = subcmd_name {
485            if self.cmd.is_args_conflicts_with_subcommands_set() && valid_arg_found {
486                return Err(ClapError::subcommand_conflict(
487                    self.cmd,
488                    pos_sc_name.clone(),
489                    matcher
490                        .arg_ids()
491                        // skip groups
492                        .filter_map(|id| self.cmd.find(id).map(|a| a.to_string()))
493                        .collect(),
494                    Usage::new(self.cmd).create_usage_with_title(&[]),
495                ));
496            }
497            let sc_name = self
498                .cmd
499                .find_subcommand(pos_sc_name)
500                .expect(INTERNAL_ERROR_MSG)
501                .get_name()
502                .to_owned();
503            match self.parse_subcommand(&sc_name, matcher, raw_args, args_cursor,
        keep_state) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
};ok!(self.parse_subcommand(&sc_name, matcher, raw_args, args_cursor, keep_state));
504        }
505
506        Ok(())
507    }
508
509    fn match_arg_error(
510        &self,
511        arg_os: &clap_lex::ParsedArg<'_>,
512        valid_arg_found: bool,
513        trailing_values: bool,
514        matcher: &ArgMatcher,
515    ) -> ClapError {
516        // If argument follows a `--`
517        if trailing_values {
518            // If the arg matches a subcommand name, or any of its aliases (if defined)
519            if self
520                .possible_subcommand(arg_os.to_value(), valid_arg_found)
521                .is_some()
522            {
523                return ClapError::unnecessary_double_dash(
524                    self.cmd,
525                    arg_os.display().to_string(),
526                    Usage::new(self.cmd).create_usage_with_title(&[]),
527                );
528            }
529        }
530
531        let suggested_trailing_arg = !trailing_values
532            && self.cmd.has_positionals()
533            && (arg_os.is_long() || arg_os.is_short());
534
535        if self.cmd.has_subcommands() {
536            if self.cmd.is_args_conflicts_with_subcommands_set() && valid_arg_found {
537                return ClapError::subcommand_conflict(
538                    self.cmd,
539                    arg_os.display().to_string(),
540                    matcher
541                        .arg_ids()
542                        .filter_map(|id| self.cmd.find(id).map(|a| a.to_string()))
543                        .collect(),
544                    Usage::new(self.cmd).create_usage_with_title(&[]),
545                );
546            }
547
548            let candidates = suggestions::did_you_mean(
549                &arg_os.display().to_string(),
550                self.cmd.all_subcommand_names(),
551            );
552            // If the argument looks like a subcommand.
553            if !candidates.is_empty() {
554                return ClapError::invalid_subcommand(
555                    self.cmd,
556                    arg_os.display().to_string(),
557                    candidates,
558                    self.cmd.get_bin_name_fallback().to_owned(),
559                    suggested_trailing_arg,
560                    Usage::new(self.cmd).create_usage_with_title(&[]),
561                );
562            }
563
564            // If the argument must be a subcommand.
565            if !self.cmd.has_positionals() || self.cmd.is_infer_subcommands_set() {
566                return ClapError::unrecognized_subcommand(
567                    self.cmd,
568                    arg_os.display().to_string(),
569                    Usage::new(self.cmd).create_usage_with_title(&[]),
570                );
571            }
572        }
573
574        ClapError::unknown_argument(
575            self.cmd,
576            arg_os.display().to_string(),
577            None,
578            suggested_trailing_arg,
579            Usage::new(self.cmd).create_usage_with_title(&[]),
580        )
581    }
582
583    // Checks if the arg matches a subcommand name, or any of its aliases (if defined)
584    fn possible_subcommand(
585        &self,
586        arg: Result<&str, &OsStr>,
587        valid_arg_found: bool,
588    ) -> Option<&str> {
589        debug!("Parser::possible_subcommand: arg={arg:?}");
590        let arg = match arg.ok() { Some(val) => val, None => { return None; } }some!(arg.ok());
591
592        if !(self.cmd.is_args_conflicts_with_subcommands_set() && valid_arg_found) {
593            if self.cmd.is_infer_subcommands_set() {
594                // For subcommand `test`, we accepts it's prefix: `t`, `te`,
595                // `tes` and `test`.
596                let mut iter = self.cmd.get_subcommands().filter_map(|s| {
597                    if s.get_name().starts_with(arg) {
598                        return Some(s.get_name());
599                    }
600
601                    // Use find here instead of chaining the iterator because we want to accept
602                    // conflicts in aliases.
603                    s.get_all_aliases().find(|s| s.starts_with(arg))
604                });
605
606                if let name @ Some(_) = iter.next() {
607                    if iter.next().is_none() {
608                        return name;
609                    }
610                }
611            }
612            // Don't use an else here because we want inference to support exact matching even if
613            // there are conflicts.
614            if let Some(sc) = self.cmd.find_subcommand(arg) {
615                return Some(sc.get_name());
616            }
617        }
618        None
619    }
620
621    // Checks if the arg matches a long flag subcommand name, or any of its aliases (if defined)
622    fn possible_long_flag_subcommand(&self, arg: &str) -> Option<&str> {
623        debug!("Parser::possible_long_flag_subcommand: arg={arg:?}");
624        if self.cmd.is_infer_subcommands_set() {
625            let mut iter = self.cmd.get_subcommands().filter_map(|sc| {
626                sc.get_long_flag().and_then(|long| {
627                    if long.starts_with(arg) {
628                        Some(sc.get_name())
629                    } else {
630                        sc.get_all_long_flag_aliases().find_map(|alias| {
631                            if alias.starts_with(arg) {
632                                Some(sc.get_name())
633                            } else {
634                                None
635                            }
636                        })
637                    }
638                })
639            });
640
641            if let name @ Some(_) = iter.next() {
642                if iter.next().is_none() {
643                    return name;
644                }
645            }
646        }
647        if let Some(sc_name) = self.cmd.find_long_subcmd(arg) {
648            return Some(sc_name);
649        }
650        None
651    }
652
653    fn parse_help_subcommand(
654        &self,
655        cmds: impl Iterator<Item = &'cmd OsStr>,
656    ) -> ClapResult<std::convert::Infallible> {
657        debug!("Parser::parse_help_subcommand");
658
659        let mut cmd = self.cmd.clone();
660        let sc = {
661            let mut sc = &mut cmd;
662
663            for cmd in cmds {
664                sc = if let Some(sc_name) =
665                    sc.find_subcommand(cmd).map(|sc| sc.get_name().to_owned())
666                {
667                    sc._build_subcommand(&sc_name).unwrap()
668                } else {
669                    return Err(ClapError::unrecognized_subcommand(
670                        sc,
671                        cmd.to_string_lossy().into_owned(),
672                        Usage::new(sc).create_usage_with_title(&[]),
673                    ));
674                };
675            }
676
677            sc
678        };
679        let parser = Parser::new(sc);
680
681        Err(parser.help_err(true))
682    }
683
684    fn is_new_arg(&self, next: &clap_lex::ParsedArg<'_>, current_positional: &Arg) -> bool {
685        #![allow(clippy::needless_bool)] // Prefer consistent if/else-if ladder
686
687        debug!(
688            "Parser::is_new_arg: {:?}:{}",
689            next.to_value_os(),
690            current_positional.get_id()
691        );
692
693        if self.cmd[current_positional.get_id()].is_allow_hyphen_values_set()
694            || (self.cmd[current_positional.get_id()].is_allow_negative_numbers_set()
695                && next.is_negative_number())
696        {
697            // If allow hyphen, this isn't a new arg.
698            debug!("Parser::is_new_arg: Allow hyphen");
699            false
700        } else if next.is_long() {
701            // If this is a long flag, this is a new arg.
702            debug!("Parser::is_new_arg: --<something> found");
703            true
704        } else if next.is_short() {
705            // If this is a short flag, this is a new arg. But a single '-' by
706            // itself is a value and typically means "stdin" on unix systems.
707            debug!("Parser::is_new_arg: -<something> found");
708            true
709        } else {
710            // Nothing special, this is a value.
711            debug!("Parser::is_new_arg: value");
712            false
713        }
714    }
715
716    fn parse_subcommand(
717        &mut self,
718        sc_name: &str,
719        matcher: &mut ArgMatcher,
720        raw_args: &mut clap_lex::RawArgs,
721        args_cursor: clap_lex::ArgCursor,
722        keep_state: bool,
723    ) -> ClapResult<()> {
724        debug!("Parser::parse_subcommand");
725
726        let partial_parsing_enabled = self.cmd.is_ignore_errors_set();
727
728        if let Some(sc) = self.cmd._build_subcommand(sc_name) {
729            let mut sc_matcher = ArgMatcher::new(sc);
730
731            debug!(
732                "Parser::parse_subcommand: About to parse sc={}",
733                sc.get_name()
734            );
735
736            {
737                let mut p = Parser::new(sc);
738                // HACK: maintain indexes between parsers
739                // FlagSubCommand short arg needs to revisit the current short args, but skip the subcommand itself
740                if keep_state {
741                    p.cur_idx.set(self.cur_idx.get());
742                    p.flag_subcmd_at = self.flag_subcmd_at;
743                    p.flag_subcmd_skip = self.flag_subcmd_skip;
744                }
745                if let Err(error) = p.get_matches_with(&mut sc_matcher, raw_args, args_cursor) {
746                    if partial_parsing_enabled && error.use_stderr() {
747                        debug!(
748                            "Parser::parse_subcommand: ignored error in subcommand {sc_name}: {error:?}"
749                        );
750                    } else {
751                        return Err(error);
752                    }
753                }
754            }
755            matcher.subcommand(SubCommand {
756                name: sc.get_name().to_owned(),
757                matches: sc_matcher.into_inner(),
758            });
759        }
760        Ok(())
761    }
762
763    fn parse_long_arg(
764        &mut self,
765        matcher: &mut ArgMatcher,
766        long_arg: Result<&str, &OsStr>,
767        long_value: Option<&OsStr>,
768        parse_state: &ParseState,
769        pos_counter: usize,
770        valid_arg_found: &mut bool,
771    ) -> ClapResult<ParseResult> {
772        // maybe here lifetime should be 'a
773        debug!("Parser::parse_long_arg");
774
775        #[allow(clippy::blocks_in_conditions)]
776        if #[allow(non_exhaustive_omitted_patterns)] match parse_state {
    ParseState::Opt(opt) | ParseState::Pos(opt) if
        self.cmd[opt].is_allow_hyphen_values_set() => true,
    _ => false,
}matches!(parse_state, ParseState::Opt(opt) | ParseState::Pos(opt) if
777            self.cmd[opt].is_allow_hyphen_values_set())
778        {
779            debug!("Parser::parse_long_arg: prior arg accepts hyphenated values",);
780            return Ok(ParseResult::MaybeHyphenValue);
781        }
782
783        debug!("Parser::parse_long_arg: Does it contain '='...");
784        let long_arg = match long_arg {
785            Ok(long_arg) => long_arg,
786            Err(long_arg_os) => {
787                return Ok(ParseResult::NoMatchingArg {
788                    arg: long_arg_os.to_string_lossy().into_owned(),
789                });
790            }
791        };
792        if long_arg.is_empty() {
793            if true {
    if !long_value.is_some() {
        {
            ::core::panicking::panic_fmt(format_args!("`--` should be filtered out before this point"));
        }
    };
};debug_assert!(
794                long_value.is_some(),
795                "`--` should be filtered out before this point"
796            );
797        }
798
799        let arg = if let Some(arg) = self.cmd.get_keymap().get(long_arg) {
800            debug!("Parser::parse_long_arg: Found valid arg or flag '{arg}'");
801            Some((long_arg, arg))
802        } else if self.cmd.is_infer_long_args_set() {
803            let mut iter = self.cmd.get_arguments().filter_map(|a| {
804                if let Some(long) = a.get_long() {
805                    if long.starts_with(long_arg) {
806                        return Some((long, a));
807                    }
808                }
809                a.aliases
810                    .iter()
811                    .find_map(|(alias, _)| alias.starts_with(long_arg).then(|| (alias.as_str(), a)))
812            });
813
814            iter.next().filter(|_| iter.next().is_none())
815        } else {
816            None
817        };
818
819        if let Some((_long_arg, arg)) = arg {
820            let ident = Identifier::Long;
821            *valid_arg_found = true;
822            if arg.is_takes_value_set() {
823                debug!(
824                    "Parser::parse_long_arg({:?}): Found an arg with value '{:?}'",
825                    long_arg, &long_value
826                );
827                let has_eq = long_value.is_some();
828                self.parse_opt_value(ident, long_value, arg, matcher, has_eq)
829            } else if let Some(rest) = long_value {
830                let required = self.cmd.required_graph();
831                debug!("Parser::parse_long_arg({long_arg:?}): Got invalid literal `{rest:?}`");
832                let mut used: Vec<Id> = matcher
833                    .arg_ids()
834                    .filter(|arg_id| {
835                        matcher.check_explicit(arg_id, &crate::builder::ArgPredicate::IsPresent)
836                    })
837                    .filter(|&n| {
838                        self.cmd
839                            .find(n)
840                            .map(|a| !(a.is_hide_set() || required.contains(a.get_id())))
841                            .unwrap_or(true)
842                    })
843                    .cloned()
844                    .collect();
845                used.push(arg.get_id().clone());
846
847                Ok(ParseResult::UnneededAttachedValue {
848                    rest: rest.to_string_lossy().into_owned(),
849                    used,
850                    arg: arg.to_string(),
851                })
852            } else {
853                debug!("Parser::parse_long_arg({long_arg:?}): Presence validated");
854                let trailing_idx = None;
855                self.react(
856                    Some(ident),
857                    ValueSource::CommandLine,
858                    arg,
859                    ::alloc::vec::Vec::new()vec![],
860                    trailing_idx,
861                    matcher,
862                )
863            }
864        } else if let Some(sc_name) = self.possible_long_flag_subcommand(long_arg) {
865            Ok(ParseResult::FlagSubCommand(sc_name.to_string()))
866        } else if self
867            .cmd
868            .get_keymap()
869            .get(&pos_counter)
870            .map(|arg| arg.is_allow_hyphen_values_set() && !arg.is_last_set())
871            .unwrap_or_default()
872        {
873            debug!("Parser::parse_long_args: positional at {pos_counter} allows hyphens");
874            Ok(ParseResult::MaybeHyphenValue)
875        } else {
876            Ok(ParseResult::NoMatchingArg {
877                arg: long_arg.to_owned(),
878            })
879        }
880    }
881
882    fn parse_short_arg(
883        &mut self,
884        matcher: &mut ArgMatcher,
885        mut short_arg: clap_lex::ShortFlags<'_>,
886        parse_state: &ParseState,
887        // change this to possible pos_arg when removing the usage of &mut Parser.
888        pos_counter: usize,
889        valid_arg_found: &mut bool,
890    ) -> ClapResult<ParseResult> {
891        debug!("Parser::parse_short_arg: short_arg={short_arg:?}");
892
893        #[allow(clippy::blocks_in_conditions)]
894        if #[allow(non_exhaustive_omitted_patterns)] match parse_state {
    ParseState::Opt(opt) | ParseState::Pos(opt) if
        self.cmd[opt].is_allow_hyphen_values_set() ||
            (self.cmd[opt].is_allow_negative_numbers_set() &&
                    short_arg.is_negative_number()) => true,
    _ => false,
}matches!(parse_state, ParseState::Opt(opt) | ParseState::Pos(opt)
895                if self.cmd[opt].is_allow_hyphen_values_set() || (self.cmd[opt].is_allow_negative_numbers_set() && short_arg.is_negative_number()))
896        {
897            debug!("Parser::parse_short_args: prior arg accepts hyphenated values",);
898            return Ok(ParseResult::MaybeHyphenValue);
899        } else if self
900            .cmd
901            .get_keymap()
902            .get(&pos_counter)
903            .map(|arg| arg.is_allow_negative_numbers_set())
904            .unwrap_or_default()
905            && short_arg.is_negative_number()
906        {
907            debug!("Parser::parse_short_arg: negative number");
908            return Ok(ParseResult::MaybeHyphenValue);
909        } else if self
910            .cmd
911            .get_keymap()
912            .get(&pos_counter)
913            .map(|arg| arg.is_allow_hyphen_values_set() && !arg.is_last_set())
914            .unwrap_or_default()
915            && short_arg
916                .clone()
917                .any(|c| !c.map(|c| self.cmd.contains_short(c)).unwrap_or_default())
918        {
919            debug!("Parser::parse_short_args: positional at {pos_counter} allows hyphens");
920            return Ok(ParseResult::MaybeHyphenValue);
921        }
922
923        let mut ret = ParseResult::NoArg;
924
925        let skip = self.flag_subcmd_skip;
926        self.flag_subcmd_skip = 0;
927        let res = short_arg.advance_by(skip);
928        if true {
    match (&res, &Ok(())) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val,
                    ::core::option::Option::Some(format_args!("tracking of `flag_subcmd_skip` is off for `{0:?}`",
                            short_arg)));
            }
        }
    };
};debug_assert_eq!(
929            res,
930            Ok(()),
931            "tracking of `flag_subcmd_skip` is off for `{short_arg:?}`"
932        );
933        while let Some(c) = short_arg.next_flag() {
934            let c = match c {
935                Ok(c) => c,
936                Err(rest) => {
937                    return Ok(ParseResult::NoMatchingArg {
938                        arg: ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("-{0}", rest.to_string_lossy()))
    })format!("-{}", rest.to_string_lossy()),
939                    });
940                }
941            };
942            debug!("Parser::parse_short_arg:iter:{c}");
943
944            // Check for matching short options, and return the name if there is no trailing
945            // concatenated value: -oval
946            // Option: -o
947            // Value: val
948            if let Some(arg) = self.cmd.get_keymap().get(&c) {
949                let ident = Identifier::Short;
950                debug!("Parser::parse_short_arg:iter:{c}: Found valid opt or flag");
951                *valid_arg_found = true;
952                if !arg.is_takes_value_set() {
953                    let arg_values = Vec::new();
954                    let trailing_idx = None;
955                    ret = match self.react(Some(ident), ValueSource::CommandLine, arg, arg_values,
        trailing_idx, matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
}ok!(self.react(
956                        Some(ident),
957                        ValueSource::CommandLine,
958                        arg,
959                        arg_values,
960                        trailing_idx,
961                        matcher,
962                    ));
963                    continue;
964                }
965
966                // Check for trailing concatenated value
967                //
968                // Cloning the iterator, so we rollback if it isn't there.
969                let val = short_arg.clone().next_value_os().unwrap_or_default();
970                debug!("Parser::parse_short_arg:iter:{c}: val={val:?}, short_arg={short_arg:?}");
971                let val = Some(val).filter(|v| !v.is_empty());
972
973                // Default to "we're expecting a value later".
974                //
975                // If attached value is not consumed, we may have more short
976                // flags to parse, continue.
977                //
978                // e.g. `-xvf`, when require_equals && x.min_vals == 0, we don't
979                // consume the `vf`, even if it's provided as value.
980                let (val, has_eq) = if let Some(val) = val.and_then(|v| v.strip_prefix("=")) {
981                    (Some(val), true)
982                } else {
983                    (val, false)
984                };
985                match match self.parse_opt_value(ident, val, arg, matcher, has_eq) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
}ok!(self.parse_opt_value(ident, val, arg, matcher, has_eq)) {
986                    ParseResult::AttachedValueNotConsumed => continue,
987                    x => return Ok(x),
988                }
989            }
990
991            return if let Some(sc_name) = self.cmd.find_short_subcmd(c) {
992                debug!("Parser::parse_short_arg:iter:{c}: subcommand={sc_name}");
993                // Make sure indices get updated before reading `self.cur_idx`
994                match self.resolve_pending(matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
};ok!(self.resolve_pending(matcher));
995                self.cur_idx.set(self.cur_idx.get() + 1);
996                debug!("Parser::parse_short_arg: cur_idx:={}", self.cur_idx.get());
997
998                let name = sc_name.to_string();
999                // Get the index of the previously saved flag subcommand in the group of flags (if exists).
1000                // If it is a new flag subcommand, then the formentioned index should be the current one
1001                // (ie. `cur_idx`), and should be registered.
1002                let cur_idx = self.cur_idx.get();
1003                self.flag_subcmd_at.get_or_insert(cur_idx);
1004                let done_short_args = short_arg.is_empty();
1005                if done_short_args {
1006                    self.flag_subcmd_at = None;
1007                }
1008                Ok(ParseResult::FlagSubCommand(name))
1009            } else {
1010                Ok(ParseResult::NoMatchingArg {
1011                    arg: ::alloc::__export::must_use({ ::alloc::fmt::format(format_args!("-{0}", c)) })format!("-{c}"),
1012                })
1013            };
1014        }
1015        Ok(ret)
1016    }
1017
1018    fn parse_opt_value(
1019        &self,
1020        ident: Identifier,
1021        attached_value: Option<&OsStr>,
1022        arg: &Arg,
1023        matcher: &mut ArgMatcher,
1024        has_eq: bool,
1025    ) -> ClapResult<ParseResult> {
1026        debug!(
1027            "Parser::parse_opt_value; arg={}, val={:?}, has_eq={:?}",
1028            arg.get_id(),
1029            attached_value,
1030            has_eq
1031        );
1032        debug!("Parser::parse_opt_value; arg.settings={:?}", arg.settings);
1033
1034        debug!("Parser::parse_opt_value; Checking for val...");
1035        // require_equals is set, but no '=' is provided, try throwing error.
1036        if arg.is_require_equals_set() && !has_eq {
1037            if arg.get_min_vals() == 0 {
1038                debug!("Requires equals, but min_vals == 0");
1039                let arg_values = Vec::new();
1040                let trailing_idx = None;
1041                let react_result = match self.react(Some(ident), ValueSource::CommandLine, arg, arg_values,
        trailing_idx, matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
}ok!(self.react(
1042                    Some(ident),
1043                    ValueSource::CommandLine,
1044                    arg,
1045                    arg_values,
1046                    trailing_idx,
1047                    matcher,
1048                ));
1049                if true {
    match (&react_result, &ParseResult::ValuesDone) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    };
};debug_assert_eq!(react_result, ParseResult::ValuesDone);
1050                if attached_value.is_some() {
1051                    Ok(ParseResult::AttachedValueNotConsumed)
1052                } else {
1053                    Ok(ParseResult::ValuesDone)
1054                }
1055            } else {
1056                debug!("Requires equals but not provided. Error.");
1057                Ok(ParseResult::EqualsNotProvided {
1058                    arg: arg.to_string(),
1059                })
1060            }
1061        } else if let Some(v) = attached_value {
1062            let arg_values = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [v.to_owned()]))vec![v.to_owned()];
1063            let trailing_idx = None;
1064            let react_result = match self.react(Some(ident), ValueSource::CommandLine, arg, arg_values,
        trailing_idx, matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
}ok!(self.react(
1065                Some(ident),
1066                ValueSource::CommandLine,
1067                arg,
1068                arg_values,
1069                trailing_idx,
1070                matcher,
1071            ));
1072            if true {
    match (&react_result, &ParseResult::ValuesDone) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    };
};debug_assert_eq!(react_result, ParseResult::ValuesDone);
1073            // Attached are always done
1074            Ok(ParseResult::ValuesDone)
1075        } else {
1076            debug!("Parser::parse_opt_value: More arg vals required...");
1077            match self.resolve_pending(matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
};ok!(self.resolve_pending(matcher));
1078            let trailing_values = false;
1079            matcher.pending_values_mut(arg.get_id(), Some(ident), trailing_values);
1080            Ok(ParseResult::Opt(arg.get_id().clone()))
1081        }
1082    }
1083
1084    fn check_terminator(&self, arg: &Arg, val: &OsStr) -> Option<ParseResult> {
1085        if Some(val) == arg.terminator.as_ref().map(|s| OsStr::new(s.as_str())) {
1086            debug!("Parser::check_terminator: terminator={:?}", arg.terminator);
1087            Some(ParseResult::ValuesDone)
1088        } else {
1089            None
1090        }
1091    }
1092
1093    fn push_arg_values(
1094        &self,
1095        arg: &Arg,
1096        raw_vals: Vec<OsString>,
1097        source: ValueSource,
1098        matcher: &mut ArgMatcher,
1099    ) -> ClapResult<()> {
1100        debug!("Parser::push_arg_values: {raw_vals:?}");
1101
1102        for raw_val in raw_vals {
1103            // update the current index because each value is a distinct index to clap
1104            self.cur_idx.set(self.cur_idx.get() + 1);
1105            debug!(
1106                "Parser::add_single_val_to_arg: cur_idx:={}",
1107                self.cur_idx.get()
1108            );
1109            let value_parser = arg.get_value_parser();
1110            let val = match value_parser.parse_ref(self.cmd, Some(arg), &raw_val, source) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
}ok!(value_parser.parse_ref(self.cmd, Some(arg), &raw_val, source));
1111
1112            matcher.add_val_to(arg.get_id(), val, raw_val);
1113            matcher.add_index_to(arg.get_id(), self.cur_idx.get());
1114        }
1115
1116        Ok(())
1117    }
1118
1119    fn resolve_pending(&self, matcher: &mut ArgMatcher) -> ClapResult<()> {
1120        let pending = match matcher.take_pending() {
1121            Some(pending) => pending,
1122            None => {
1123                return Ok(());
1124            }
1125        };
1126
1127        debug!("Parser::resolve_pending: id={:?}", pending.id);
1128        let arg = self.cmd.find(&pending.id).expect(INTERNAL_ERROR_MSG);
1129        let _ = match self.react(pending.ident, ValueSource::CommandLine, arg,
        pending.raw_vals, pending.trailing_idx, matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
}ok!(self.react(
1130            pending.ident,
1131            ValueSource::CommandLine,
1132            arg,
1133            pending.raw_vals,
1134            pending.trailing_idx,
1135            matcher,
1136        ));
1137
1138        Ok(())
1139    }
1140
1141    fn react(
1142        &self,
1143        ident: Option<Identifier>,
1144        source: ValueSource,
1145        arg: &Arg,
1146        mut raw_vals: Vec<OsString>,
1147        mut trailing_idx: Option<usize>,
1148        matcher: &mut ArgMatcher,
1149    ) -> ClapResult<ParseResult> {
1150        match self.resolve_pending(matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
};ok!(self.resolve_pending(matcher));
1151
1152        debug!(
1153            "Parser::react action={:?}, identifier={:?}, source={:?}",
1154            arg.get_action(),
1155            ident,
1156            source
1157        );
1158
1159        // Process before `default_missing_values` to avoid it counting as values from the command
1160        // line
1161        if source == ValueSource::CommandLine {
1162            match self.verify_num_args(arg, &raw_vals) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
};ok!(self.verify_num_args(arg, &raw_vals));
1163        }
1164
1165        if raw_vals.is_empty() {
1166            // We assume this case is valid: require equals, but min_vals == 0.
1167            if !arg.default_missing_vals.is_empty() {
1168                debug!("Parser::react: has default_missing_vals");
1169                trailing_idx = None;
1170                raw_vals.extend(
1171                    arg.default_missing_vals
1172                        .iter()
1173                        .map(|s| s.as_os_str().to_owned()),
1174                );
1175            }
1176        }
1177
1178        if let Some(val_delim) = arg.get_value_delimiter() {
1179            if self.cmd.is_dont_delimit_trailing_values_set() && trailing_idx == Some(0) {
1180                // Nothing to do
1181            } else {
1182                let mut val_delim_buffer = [0; 4];
1183                let val_delim = val_delim.encode_utf8(&mut val_delim_buffer);
1184                let mut split_raw_vals = Vec::with_capacity(raw_vals.len());
1185                for (i, raw_val) in raw_vals.into_iter().enumerate() {
1186                    if !raw_val.contains(val_delim)
1187                        || (self.cmd.is_dont_delimit_trailing_values_set()
1188                            && trailing_idx == Some(i))
1189                    {
1190                        split_raw_vals.push(raw_val);
1191                    } else {
1192                        split_raw_vals.extend(raw_val.split(val_delim).map(|x| x.to_owned()));
1193                    }
1194                }
1195                raw_vals = split_raw_vals;
1196            }
1197        }
1198
1199        match arg.get_action() {
1200            ArgAction::Set => {
1201                if source == ValueSource::CommandLine
1202                    && #[allow(non_exhaustive_omitted_patterns)] match ident {
    Some(Identifier::Short) | Some(Identifier::Long) => true,
    _ => false,
}matches!(ident, Some(Identifier::Short) | Some(Identifier::Long))
1203                {
1204                    // Record flag's index
1205                    self.cur_idx.set(self.cur_idx.get() + 1);
1206                    debug!("Parser::react: cur_idx:={}", self.cur_idx.get());
1207                }
1208                if matcher.remove(arg.get_id())
1209                    && !(self.cmd.is_args_override_self() || arg.overrides.contains(arg.get_id()))
1210                {
1211                    return Err(ClapError::argument_conflict(
1212                        self.cmd,
1213                        arg.to_string(),
1214                        ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [arg.to_string()]))vec![arg.to_string()],
1215                        Usage::new(self.cmd).create_usage_with_title(&[]),
1216                    ));
1217                }
1218                self.start_custom_arg(matcher, arg, source);
1219                match self.push_arg_values(arg, raw_vals, source, matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
};ok!(self.push_arg_values(arg, raw_vals, source, matcher));
1220                if truecfg!(debug_assertions) && matcher.needs_more_vals(arg) {
1221                    debug!(
1222                        "Parser::react not enough values passed in, leaving it to the validator to complain",
1223                    );
1224                }
1225                Ok(ParseResult::ValuesDone)
1226            }
1227            ArgAction::Append => {
1228                if source == ValueSource::CommandLine
1229                    && #[allow(non_exhaustive_omitted_patterns)] match ident {
    Some(Identifier::Short) | Some(Identifier::Long) => true,
    _ => false,
}matches!(ident, Some(Identifier::Short) | Some(Identifier::Long))
1230                {
1231                    // Record flag's index
1232                    self.cur_idx.set(self.cur_idx.get() + 1);
1233                    debug!("Parser::react: cur_idx:={}", self.cur_idx.get());
1234                }
1235                self.start_custom_arg(matcher, arg, source);
1236                match self.push_arg_values(arg, raw_vals, source, matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
};ok!(self.push_arg_values(arg, raw_vals, source, matcher));
1237                if truecfg!(debug_assertions) && matcher.needs_more_vals(arg) {
1238                    debug!(
1239                        "Parser::react not enough values passed in, leaving it to the validator to complain",
1240                    );
1241                }
1242                Ok(ParseResult::ValuesDone)
1243            }
1244            ArgAction::SetTrue => {
1245                let raw_vals = if raw_vals.is_empty() {
1246                    ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [OsString::from("true")]))vec![OsString::from("true")]
1247                } else {
1248                    raw_vals
1249                };
1250
1251                if matcher.remove(arg.get_id())
1252                    && !(self.cmd.is_args_override_self() || arg.overrides.contains(arg.get_id()))
1253                {
1254                    return Err(ClapError::argument_conflict(
1255                        self.cmd,
1256                        arg.to_string(),
1257                        ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [arg.to_string()]))vec![arg.to_string()],
1258                        Usage::new(self.cmd).create_usage_with_title(&[]),
1259                    ));
1260                }
1261                self.start_custom_arg(matcher, arg, source);
1262                match self.push_arg_values(arg, raw_vals, source, matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
};ok!(self.push_arg_values(arg, raw_vals, source, matcher));
1263                Ok(ParseResult::ValuesDone)
1264            }
1265            ArgAction::SetFalse => {
1266                let raw_vals = if raw_vals.is_empty() {
1267                    ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [OsString::from("false")]))vec![OsString::from("false")]
1268                } else {
1269                    raw_vals
1270                };
1271
1272                if matcher.remove(arg.get_id())
1273                    && !(self.cmd.is_args_override_self() || arg.overrides.contains(arg.get_id()))
1274                {
1275                    return Err(ClapError::argument_conflict(
1276                        self.cmd,
1277                        arg.to_string(),
1278                        ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [arg.to_string()]))vec![arg.to_string()],
1279                        Usage::new(self.cmd).create_usage_with_title(&[]),
1280                    ));
1281                }
1282                self.start_custom_arg(matcher, arg, source);
1283                match self.push_arg_values(arg, raw_vals, source, matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
};ok!(self.push_arg_values(arg, raw_vals, source, matcher));
1284                Ok(ParseResult::ValuesDone)
1285            }
1286            ArgAction::Count => {
1287                let raw_vals = if raw_vals.is_empty() {
1288                    let existing_value = *matcher
1289                        .get_one::<crate::builder::CountType>(arg.get_id().as_str())
1290                        .unwrap_or(&0);
1291                    let next_value = existing_value.saturating_add(1);
1292                    ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [OsString::from(next_value.to_string())]))vec![OsString::from(next_value.to_string())]
1293                } else {
1294                    raw_vals
1295                };
1296
1297                matcher.remove(arg.get_id());
1298                self.start_custom_arg(matcher, arg, source);
1299                match self.push_arg_values(arg, raw_vals, source, matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
};ok!(self.push_arg_values(arg, raw_vals, source, matcher));
1300                Ok(ParseResult::ValuesDone)
1301            }
1302            ArgAction::Help => {
1303                let use_long = match ident {
1304                    Some(Identifier::Long) => true,
1305                    Some(Identifier::Short) => false,
1306                    Some(Identifier::Index) => true,
1307                    None => true,
1308                };
1309                debug!("Help: use_long={use_long}");
1310                Err(self.help_err(use_long))
1311            }
1312            ArgAction::HelpShort => {
1313                let use_long = false;
1314                debug!("Help: use_long={use_long}");
1315                Err(self.help_err(use_long))
1316            }
1317            ArgAction::HelpLong => {
1318                let use_long = true;
1319                debug!("Help: use_long={use_long}");
1320                Err(self.help_err(use_long))
1321            }
1322            ArgAction::Version => {
1323                let use_long = match ident {
1324                    Some(Identifier::Long) => true,
1325                    Some(Identifier::Short) => false,
1326                    Some(Identifier::Index) => true,
1327                    None => true,
1328                };
1329                debug!("Version: use_long={use_long}");
1330                Err(self.version_err(use_long))
1331            }
1332        }
1333    }
1334
1335    fn verify_num_args(&self, arg: &Arg, raw_vals: &[OsString]) -> ClapResult<()> {
1336        if self.cmd.is_ignore_errors_set() {
1337            return Ok(());
1338        }
1339
1340        let actual = raw_vals.len();
1341        let expected = arg.get_num_args().expect(INTERNAL_ERROR_MSG);
1342
1343        if 0 < expected.min_values() && actual == 0 {
1344            // Issue 665 (https://github.com/clap-rs/clap/issues/665)
1345            // Issue 1105 (https://github.com/clap-rs/clap/issues/1105)
1346            return Err(ClapError::empty_value(
1347                self.cmd,
1348                &super::get_possible_values_cli(arg)
1349                    .iter()
1350                    .filter(|pv| !pv.is_hide_set())
1351                    .map(|n| n.get_name().to_owned())
1352                    .collect::<Vec<_>>(),
1353                arg.to_string(),
1354            ));
1355        } else if let Some(expected) = expected.num_values() {
1356            if expected != actual {
1357                debug!("Validator::validate_arg_num_vals: Sending error WrongNumberOfValues");
1358                return Err(ClapError::wrong_number_of_values(
1359                    self.cmd,
1360                    arg.to_string(),
1361                    expected,
1362                    actual,
1363                    Usage::new(self.cmd).create_usage_with_title(&[]),
1364                ));
1365            }
1366        } else if actual < expected.min_values() {
1367            return Err(ClapError::too_few_values(
1368                self.cmd,
1369                arg.to_string(),
1370                expected.min_values(),
1371                actual,
1372                Usage::new(self.cmd).create_usage_with_title(&[]),
1373            ));
1374        } else if expected.max_values() < actual {
1375            debug!("Validator::validate_arg_num_vals: Sending error TooManyValues");
1376            return Err(ClapError::too_many_values(
1377                self.cmd,
1378                raw_vals
1379                    .last()
1380                    .expect(INTERNAL_ERROR_MSG)
1381                    .to_string_lossy()
1382                    .into_owned(),
1383                arg.to_string(),
1384                Usage::new(self.cmd).create_usage_with_title(&[]),
1385            ));
1386        }
1387
1388        Ok(())
1389    }
1390
1391    fn remove_overrides(&self, arg: &Arg, matcher: &mut ArgMatcher) {
1392        debug!("Parser::remove_overrides: id={:?}", arg.id);
1393        for override_id in &arg.overrides {
1394            debug!("Parser::remove_overrides:iter:{override_id:?}: removing");
1395            matcher.remove(override_id);
1396        }
1397
1398        // Override anything that can override us
1399        let mut transitive = Vec::new();
1400        for arg_id in matcher.arg_ids() {
1401            if let Some(overrider) = self.cmd.find(arg_id) {
1402                if overrider.overrides.contains(arg.get_id()) {
1403                    transitive.push(overrider.get_id());
1404                }
1405            }
1406        }
1407        for overrider_id in transitive {
1408            debug!("Parser::remove_overrides:iter:{overrider_id:?}: removing");
1409            matcher.remove(overrider_id);
1410        }
1411    }
1412
1413    #[cfg(feature = "env")]
1414    fn add_env(&mut self, matcher: &mut ArgMatcher) -> ClapResult<()> {
1415        debug!("Parser::add_env");
1416
1417        for arg in self.cmd.get_arguments() {
1418            // Use env only if the arg was absent among command line args,
1419            // early return if this is not the case.
1420            if matcher.contains(&arg.id) {
1421                debug!("Parser::add_env: Skipping existing arg `{arg}`");
1422                continue;
1423            }
1424
1425            debug!("Parser::add_env: Checking arg `{arg}`");
1426            if let Some((_, Some(ref val))) = arg.env {
1427                debug!("Parser::add_env: Found an opt with value={val:?}");
1428                let arg_values = vec![val.to_owned()];
1429                let trailing_idx = None;
1430                let _ = ok!(self.react(
1431                    None,
1432                    ValueSource::EnvVariable,
1433                    arg,
1434                    arg_values,
1435                    trailing_idx,
1436                    matcher,
1437                ));
1438            }
1439        }
1440
1441        Ok(())
1442    }
1443
1444    fn add_defaults(&self, matcher: &mut ArgMatcher) -> ClapResult<()> {
1445        debug!("Parser::add_defaults");
1446
1447        for arg in self.cmd.get_arguments() {
1448            debug!("Parser::add_defaults:iter:{}:", arg.get_id());
1449            match self.add_default_value(arg, matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
};ok!(self.add_default_value(arg, matcher));
1450        }
1451
1452        Ok(())
1453    }
1454
1455    fn add_default_value(&self, arg: &Arg, matcher: &mut ArgMatcher) -> ClapResult<()> {
1456        if !arg.default_vals_ifs.is_empty() {
1457            debug!("Parser::add_default_value: has conditional defaults");
1458            if !matcher.contains(arg.get_id()) {
1459                for (id, val, default) in arg.default_vals_ifs.iter() {
1460                    let add = if let Some(a) = matcher.get(id) {
1461                        match val {
1462                            crate::builder::ArgPredicate::Equals(v) => {
1463                                a.raw_vals_flatten().any(|value| v == value)
1464                            }
1465                            crate::builder::ArgPredicate::IsPresent => true,
1466                        }
1467                    } else {
1468                        false
1469                    };
1470
1471                    if add {
1472                        if let Some(default) = default {
1473                            let arg_values =
1474                                default.iter().map(|os_str| os_str.to_os_string()).collect();
1475                            let trailing_idx = None;
1476                            let _ = match self.react(None, ValueSource::DefaultValue, arg, arg_values,
        trailing_idx, matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
}ok!(self.react(
1477                                None,
1478                                ValueSource::DefaultValue,
1479                                arg,
1480                                arg_values,
1481                                trailing_idx,
1482                                matcher,
1483                            ));
1484                        }
1485                        return Ok(());
1486                    }
1487                }
1488            }
1489        } else {
1490            debug!("Parser::add_default_value: doesn't have conditional defaults");
1491        }
1492
1493        if !arg.default_vals.is_empty() {
1494            debug!(
1495                "Parser::add_default_value:iter:{}: has default vals",
1496                arg.get_id()
1497            );
1498            if matcher.contains(arg.get_id()) {
1499                debug!("Parser::add_default_value:iter:{}: was used", arg.get_id());
1500            // do nothing
1501            } else {
1502                debug!(
1503                    "Parser::add_default_value:iter:{}: wasn't used",
1504                    arg.get_id()
1505                );
1506                let arg_values: Vec<_> = arg
1507                    .default_vals
1508                    .iter()
1509                    .map(crate::builder::OsStr::to_os_string)
1510                    .collect();
1511                let trailing_idx = None;
1512                let _ = match self.react(None, ValueSource::DefaultValue, arg, arg_values,
        trailing_idx, matcher) {
    Ok(val) => val,
    Err(err) => { return Err(err); }
}ok!(self.react(
1513                    None,
1514                    ValueSource::DefaultValue,
1515                    arg,
1516                    arg_values,
1517                    trailing_idx,
1518                    matcher,
1519                ));
1520            }
1521        } else {
1522            debug!(
1523                "Parser::add_default_value:iter:{}: doesn't have default vals",
1524                arg.get_id()
1525            );
1526
1527            // do nothing
1528        }
1529
1530        Ok(())
1531    }
1532
1533    fn start_custom_arg(&self, matcher: &mut ArgMatcher, arg: &Arg, source: ValueSource) {
1534        if source == ValueSource::CommandLine {
1535            // With each new occurrence, remove overrides from prior occurrences
1536            self.remove_overrides(arg, matcher);
1537        }
1538        matcher.start_custom_arg(arg, source);
1539        if source.is_explicit() {
1540            for group in self.cmd.groups_for_arg(arg.get_id()) {
1541                matcher.start_custom_group(group.clone(), source);
1542                matcher.add_val_to(
1543                    &group,
1544                    AnyValue::new(arg.get_id().clone()),
1545                    OsString::from(arg.get_id().as_str()),
1546                );
1547            }
1548        }
1549    }
1550}
1551
1552// Error, Help, and Version Methods
1553impl Parser<'_> {
1554    /// Is only used for the long flag(which is the only one needs fuzzy searching)
1555    fn did_you_mean_error(
1556        &mut self,
1557        arg: &str,
1558        matcher: &mut ArgMatcher,
1559        remaining_args: &[&OsStr],
1560        trailing_values: bool,
1561    ) -> ClapError {
1562        debug!("Parser::did_you_mean_error: arg={arg}");
1563        // Didn't match a flag or option
1564        let longs = self
1565            .cmd
1566            .get_keymap()
1567            .keys()
1568            .filter_map(|x| match x {
1569                KeyType::Long(l) => Some(l.to_string_lossy().into_owned()),
1570                _ => None,
1571            })
1572            .collect::<Vec<_>>();
1573        debug!("Parser::did_you_mean_error: longs={longs:?}");
1574
1575        let did_you_mean = suggestions::did_you_mean_flag(
1576            arg,
1577            remaining_args,
1578            longs.iter().map(|x| &x[..]),
1579            self.cmd.get_subcommands_mut(),
1580        );
1581
1582        // Add the arg to the matches to build a proper usage string
1583        if !self.cmd.is_ignore_errors_set() {
1584            if let Some((name, _)) = did_you_mean.as_ref() {
1585                if let Some(arg) = self.cmd.get_keymap().get(&name.as_ref()) {
1586                    self.start_custom_arg(matcher, arg, ValueSource::CommandLine);
1587                }
1588            }
1589        }
1590        let did_you_mean = did_you_mean.map(|(arg, cmd)| (::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("--{0}", arg))
    })format!("--{arg}"), cmd));
1591
1592        let required = self.cmd.required_graph();
1593        let used: Vec<Id> = matcher
1594            .arg_ids()
1595            .filter(|arg_id| {
1596                matcher.check_explicit(arg_id, &crate::builder::ArgPredicate::IsPresent)
1597            })
1598            .filter(|n| self.cmd.find(n).map(|a| !a.is_hide_set()).unwrap_or(false))
1599            .cloned()
1600            .collect();
1601
1602        // `did_you_mean` is a lot more likely and should cause us to skip the `--` suggestion
1603        // with the one exception being that the CLI is trying to capture arguments
1604        //
1605        // In theory, this is only called for `--long`s, so we don't need to check
1606        let suggested_trailing_arg = (did_you_mean.is_none()
1607            || self
1608                .cmd
1609                .get_positionals()
1610                .any(|arg| arg.is_last_set() || arg.is_trailing_var_arg_set()))
1611            && !trailing_values
1612            && self.cmd.has_positionals();
1613        ClapError::unknown_argument(
1614            self.cmd,
1615            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("--{0}", arg))
    })format!("--{arg}"),
1616            did_you_mean,
1617            suggested_trailing_arg,
1618            Usage::new(self.cmd)
1619                .required(&required)
1620                .create_usage_with_title(&used),
1621        )
1622    }
1623
1624    fn help_err(&self, use_long: bool) -> ClapError {
1625        let styled = self.cmd.write_help_err(use_long);
1626        ClapError::display_help(self.cmd, styled)
1627    }
1628
1629    fn version_err(&self, use_long: bool) -> ClapError {
1630        let styled = self.cmd.write_version_err(use_long);
1631        ClapError::display_version(self.cmd, styled)
1632    }
1633}
1634
1635#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ParseState {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            ParseState::ValuesDone =>
                ::core::fmt::Formatter::write_str(f, "ValuesDone"),
            ParseState::Opt(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Opt",
                    &__self_0),
            ParseState::Pos(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Pos",
                    &__self_0),
        }
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for ParseState {
    #[inline]
    fn eq(&self, other: &ParseState) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (ParseState::Opt(__self_0), ParseState::Opt(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (ParseState::Pos(__self_0), ParseState::Pos(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ParseState {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Id>;
    }
}Eq)]
1636pub(crate) enum ParseState {
1637    ValuesDone,
1638    Opt(Id),
1639    Pos(Id),
1640}
1641
1642/// Recoverable Parsing results.
1643#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ParseResult {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            ParseResult::FlagSubCommand(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "FlagSubCommand", &__self_0),
            ParseResult::Opt(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Opt",
                    &__self_0),
            ParseResult::ValuesDone =>
                ::core::fmt::Formatter::write_str(f, "ValuesDone"),
            ParseResult::AttachedValueNotConsumed =>
                ::core::fmt::Formatter::write_str(f,
                    "AttachedValueNotConsumed"),
            ParseResult::UnneededAttachedValue {
                rest: __self_0, used: __self_1, arg: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "UnneededAttachedValue", "rest", __self_0, "used", __self_1,
                    "arg", &__self_2),
            ParseResult::MaybeHyphenValue =>
                ::core::fmt::Formatter::write_str(f, "MaybeHyphenValue"),
            ParseResult::EqualsNotProvided { arg: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "EqualsNotProvided", "arg", &__self_0),
            ParseResult::NoMatchingArg { arg: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "NoMatchingArg", "arg", &__self_0),
            ParseResult::NoArg =>
                ::core::fmt::Formatter::write_str(f, "NoArg"),
        }
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for ParseResult {
    #[inline]
    fn eq(&self, other: &ParseResult) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (ParseResult::FlagSubCommand(__self_0),
                    ParseResult::FlagSubCommand(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (ParseResult::Opt(__self_0), ParseResult::Opt(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (ParseResult::UnneededAttachedValue {
                    rest: __self_0, used: __self_1, arg: __self_2 },
                    ParseResult::UnneededAttachedValue {
                    rest: __arg1_0, used: __arg1_1, arg: __arg1_2 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1 &&
                        __self_2 == __arg1_2,
                (ParseResult::EqualsNotProvided { arg: __self_0 },
                    ParseResult::EqualsNotProvided { arg: __arg1_0 }) =>
                    __self_0 == __arg1_0,
                (ParseResult::NoMatchingArg { arg: __self_0 },
                    ParseResult::NoMatchingArg { arg: __arg1_0 }) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::clone::Clone for ParseResult {
    #[inline]
    fn clone(&self) -> ParseResult {
        match self {
            ParseResult::FlagSubCommand(__self_0) =>
                ParseResult::FlagSubCommand(::core::clone::Clone::clone(__self_0)),
            ParseResult::Opt(__self_0) =>
                ParseResult::Opt(::core::clone::Clone::clone(__self_0)),
            ParseResult::ValuesDone => ParseResult::ValuesDone,
            ParseResult::AttachedValueNotConsumed =>
                ParseResult::AttachedValueNotConsumed,
            ParseResult::UnneededAttachedValue {
                rest: __self_0, used: __self_1, arg: __self_2 } =>
                ParseResult::UnneededAttachedValue {
                    rest: ::core::clone::Clone::clone(__self_0),
                    used: ::core::clone::Clone::clone(__self_1),
                    arg: ::core::clone::Clone::clone(__self_2),
                },
            ParseResult::MaybeHyphenValue => ParseResult::MaybeHyphenValue,
            ParseResult::EqualsNotProvided { arg: __self_0 } =>
                ParseResult::EqualsNotProvided {
                    arg: ::core::clone::Clone::clone(__self_0),
                },
            ParseResult::NoMatchingArg { arg: __self_0 } =>
                ParseResult::NoMatchingArg {
                    arg: ::core::clone::Clone::clone(__self_0),
                },
            ParseResult::NoArg => ParseResult::NoArg,
        }
    }
}Clone)]
1644#[must_use]
1645enum ParseResult {
1646    FlagSubCommand(String),
1647    Opt(Id),
1648    ValuesDone,
1649    /// Value attached to the short flag is not consumed(e.g. 'u' for `-cu` is
1650    /// not consumed).
1651    AttachedValueNotConsumed,
1652    /// This long flag doesn't need a value but is provided one.
1653    UnneededAttachedValue {
1654        rest: String,
1655        used: Vec<Id>,
1656        arg: String,
1657    },
1658    /// This flag might be an hyphen Value.
1659    MaybeHyphenValue,
1660    /// Equals required but not provided.
1661    EqualsNotProvided {
1662        arg: String,
1663    },
1664    /// Failed to match a Arg.
1665    NoMatchingArg {
1666        arg: String,
1667    },
1668    /// No argument found e.g. parser is given `-` when parsing a flag.
1669    NoArg,
1670}
1671
1672#[derive(#[automatically_derived]
impl ::core::clone::Clone for PendingArg {
    #[inline]
    fn clone(&self) -> PendingArg {
        PendingArg {
            id: ::core::clone::Clone::clone(&self.id),
            ident: ::core::clone::Clone::clone(&self.ident),
            raw_vals: ::core::clone::Clone::clone(&self.raw_vals),
            trailing_idx: ::core::clone::Clone::clone(&self.trailing_idx),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for PendingArg {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f, "PendingArg",
            "id", &self.id, "ident", &self.ident, "raw_vals", &self.raw_vals,
            "trailing_idx", &&self.trailing_idx)
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for PendingArg {
    #[inline]
    fn eq(&self, other: &PendingArg) -> bool {
        self.id == other.id && self.ident == other.ident &&
                self.raw_vals == other.raw_vals &&
            self.trailing_idx == other.trailing_idx
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for PendingArg {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Id>;
        let _: ::core::cmp::AssertParamIsEq<Option<Identifier>>;
        let _: ::core::cmp::AssertParamIsEq<Vec<OsString>>;
        let _: ::core::cmp::AssertParamIsEq<Option<usize>>;
    }
}Eq)]
1673pub(crate) struct PendingArg {
1674    pub(crate) id: Id,
1675    pub(crate) ident: Option<Identifier>,
1676    pub(crate) raw_vals: Vec<OsString>,
1677    pub(crate) trailing_idx: Option<usize>,
1678}
1679
1680#[derive(#[automatically_derived]
impl ::core::marker::Copy for Identifier { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Identifier {
    #[inline]
    fn clone(&self) -> Identifier { *self }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for Identifier {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                Identifier::Short => "Short",
                Identifier::Long => "Long",
                Identifier::Index => "Index",
            })
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for Identifier {
    #[inline]
    fn eq(&self, other: &Identifier) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Identifier {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq)]
1681pub(crate) enum Identifier {
1682    Short,
1683    Long,
1684    Index,
1685}