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