• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Internal
2 use crate::builder::{AppSettings, Arg, ArgPredicate, Command, PossibleValue};
3 use crate::error::{Error, Result as ClapResult};
4 use crate::output::fmt::Stream;
5 use crate::output::Usage;
6 use crate::parser::{ArgMatcher, MatchedArg, ParseState};
7 use crate::util::ChildGraph;
8 use crate::util::Id;
9 use crate::{INTERNAL_ERROR_MSG, INVALID_UTF8};
10 
11 pub(crate) struct Validator<'help, 'cmd> {
12     cmd: &'cmd Command<'help>,
13     required: ChildGraph<Id>,
14 }
15 
16 impl<'help, 'cmd> Validator<'help, 'cmd> {
new(cmd: &'cmd Command<'help>) -> Self17     pub(crate) fn new(cmd: &'cmd Command<'help>) -> Self {
18         let required = cmd.required_graph();
19         Validator { cmd, required }
20     }
21 
validate( &mut self, parse_state: ParseState, matcher: &mut ArgMatcher, ) -> ClapResult<()>22     pub(crate) fn validate(
23         &mut self,
24         parse_state: ParseState,
25         matcher: &mut ArgMatcher,
26     ) -> ClapResult<()> {
27         debug!("Validator::validate");
28         let mut conflicts = Conflicts::new();
29         let has_subcmd = matcher.subcommand_name().is_some();
30 
31         if let ParseState::Opt(a) = parse_state {
32             debug!("Validator::validate: needs_val_of={:?}", a);
33 
34             let o = &self.cmd[&a];
35             let should_err = if let Some(v) = matcher.args.get(&o.id) {
36                 v.all_val_groups_empty() && !(o.min_vals.is_some() && o.min_vals.unwrap() == 0)
37             } else {
38                 true
39             };
40             if should_err {
41                 return Err(Error::empty_value(
42                     self.cmd,
43                     &get_possible_values(o)
44                         .iter()
45                         .filter(|pv| !pv.is_hide_set())
46                         .map(PossibleValue::get_name)
47                         .collect::<Vec<_>>(),
48                     o.to_string(),
49                 ));
50             }
51         }
52 
53         if !has_subcmd && self.cmd.is_arg_required_else_help_set() {
54             let num_user_values = matcher
55                 .arg_ids()
56                 .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent))
57                 .count();
58             if num_user_values == 0 {
59                 let message = self.cmd.write_help_err(false, Stream::Stderr)?;
60                 return Err(Error::display_help_error(self.cmd, message));
61             }
62         }
63         #[allow(deprecated)]
64         if !has_subcmd && self.cmd.is_subcommand_required_set() {
65             let bn = self
66                 .cmd
67                 .get_bin_name()
68                 .unwrap_or_else(|| self.cmd.get_name());
69             return Err(Error::missing_subcommand(
70                 self.cmd,
71                 bn.to_string(),
72                 Usage::new(self.cmd)
73                     .required(&self.required)
74                     .create_usage_with_title(&[]),
75             ));
76         } else if !has_subcmd && self.cmd.is_set(AppSettings::SubcommandRequiredElseHelp) {
77             debug!("Validator::new::get_matches_with: SubcommandRequiredElseHelp=true");
78             let message = self.cmd.write_help_err(false, Stream::Stderr)?;
79             return Err(Error::display_help_error(self.cmd, message));
80         }
81 
82         self.validate_conflicts(matcher, &mut conflicts)?;
83         if !(self.cmd.is_subcommand_negates_reqs_set() && has_subcmd) {
84             self.validate_required(matcher, &mut conflicts)?;
85         }
86         self.validate_matched_args(matcher)?;
87 
88         Ok(())
89     }
90 
validate_arg_values(&self, arg: &Arg, ma: &MatchedArg) -> ClapResult<()>91     fn validate_arg_values(&self, arg: &Arg, ma: &MatchedArg) -> ClapResult<()> {
92         debug!("Validator::validate_arg_values: arg={:?}", arg.name);
93         for val in ma.raw_vals_flatten() {
94             if !arg.possible_vals.is_empty() {
95                 debug!(
96                     "Validator::validate_arg_values: possible_vals={:?}",
97                     arg.possible_vals
98                 );
99                 let val_str = val.to_string_lossy();
100                 let ok = arg
101                     .possible_vals
102                     .iter()
103                     .any(|pv| pv.matches(&val_str, arg.is_ignore_case_set()));
104                 if !ok {
105                     return Err(Error::invalid_value(
106                         self.cmd,
107                         val_str.into_owned(),
108                         &arg.possible_vals
109                             .iter()
110                             .filter(|pv| !pv.is_hide_set())
111                             .map(PossibleValue::get_name)
112                             .collect::<Vec<_>>(),
113                         arg.to_string(),
114                     ));
115                 }
116             }
117             {
118                 #![allow(deprecated)]
119                 if arg.is_forbid_empty_values_set() && val.is_empty() {
120                     debug!("Validator::validate_arg_values: illegal empty val found");
121                     return Err(Error::empty_value(
122                         self.cmd,
123                         &get_possible_values(arg)
124                             .iter()
125                             .filter(|pv| !pv.is_hide_set())
126                             .map(PossibleValue::get_name)
127                             .collect::<Vec<_>>(),
128                         arg.to_string(),
129                     ));
130                 }
131             }
132 
133             if let Some(ref vtor) = arg.validator {
134                 debug!("Validator::validate_arg_values: checking validator...");
135                 let mut vtor = vtor.lock().unwrap();
136                 if let Err(e) = vtor(&*val.to_string_lossy()) {
137                     debug!("error");
138                     return Err(Error::value_validation(
139                         arg.to_string(),
140                         val.to_string_lossy().into_owned(),
141                         e,
142                     )
143                     .with_cmd(self.cmd));
144                 } else {
145                     debug!("good");
146                 }
147             }
148             if let Some(ref vtor) = arg.validator_os {
149                 debug!("Validator::validate_arg_values: checking validator_os...");
150                 let mut vtor = vtor.lock().unwrap();
151                 if let Err(e) = vtor(val) {
152                     debug!("error");
153                     return Err(Error::value_validation(
154                         arg.to_string(),
155                         val.to_string_lossy().into(),
156                         e,
157                     )
158                     .with_cmd(self.cmd));
159                 } else {
160                     debug!("good");
161                 }
162             }
163         }
164         Ok(())
165     }
166 
validate_conflicts( &mut self, matcher: &ArgMatcher, conflicts: &mut Conflicts, ) -> ClapResult<()>167     fn validate_conflicts(
168         &mut self,
169         matcher: &ArgMatcher,
170         conflicts: &mut Conflicts,
171     ) -> ClapResult<()> {
172         debug!("Validator::validate_conflicts");
173 
174         self.validate_exclusive(matcher)?;
175 
176         for arg_id in matcher
177             .arg_ids()
178             .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent))
179             .filter(|arg_id| self.cmd.find(arg_id).is_some())
180         {
181             debug!("Validator::validate_conflicts::iter: id={:?}", arg_id);
182             let conflicts = conflicts.gather_conflicts(self.cmd, matcher, arg_id);
183             self.build_conflict_err(arg_id, &conflicts, matcher)?;
184         }
185 
186         Ok(())
187     }
188 
validate_exclusive(&self, matcher: &ArgMatcher) -> ClapResult<()>189     fn validate_exclusive(&self, matcher: &ArgMatcher) -> ClapResult<()> {
190         debug!("Validator::validate_exclusive");
191         let args_count = matcher
192             .arg_ids()
193             .filter(|arg_id| {
194                 matcher.check_explicit(arg_id, crate::builder::ArgPredicate::IsPresent)
195             })
196             .count();
197         if args_count <= 1 {
198             // Nothing present to conflict with
199             return Ok(());
200         }
201 
202         matcher
203             .arg_ids()
204             .filter(|arg_id| {
205                 matcher.check_explicit(arg_id, crate::builder::ArgPredicate::IsPresent)
206             })
207             .filter_map(|name| {
208                 debug!("Validator::validate_exclusive:iter:{:?}", name);
209                 self.cmd
210                     .find(name)
211                     // Find `arg`s which are exclusive but also appear with other args.
212                     .filter(|&arg| arg.is_exclusive_set() && args_count > 1)
213             })
214             // Throw an error for the first conflict found.
215             .try_for_each(|arg| {
216                 Err(Error::argument_conflict(
217                     self.cmd,
218                     arg.to_string(),
219                     Vec::new(),
220                     Usage::new(self.cmd)
221                         .required(&self.required)
222                         .create_usage_with_title(&[]),
223                 ))
224             })
225     }
226 
build_conflict_err( &self, name: &Id, conflict_ids: &[Id], matcher: &ArgMatcher, ) -> ClapResult<()>227     fn build_conflict_err(
228         &self,
229         name: &Id,
230         conflict_ids: &[Id],
231         matcher: &ArgMatcher,
232     ) -> ClapResult<()> {
233         if conflict_ids.is_empty() {
234             return Ok(());
235         }
236 
237         debug!("Validator::build_conflict_err: name={:?}", name);
238         let mut seen = std::collections::HashSet::new();
239         let conflicts = conflict_ids
240             .iter()
241             .flat_map(|c_id| {
242                 if self.cmd.find_group(c_id).is_some() {
243                     self.cmd.unroll_args_in_group(c_id)
244                 } else {
245                     vec![c_id.clone()]
246                 }
247             })
248             .filter_map(|c_id| {
249                 seen.insert(c_id.clone()).then(|| {
250                     let c_arg = self.cmd.find(&c_id).expect(INTERNAL_ERROR_MSG);
251                     c_arg.to_string()
252                 })
253             })
254             .collect();
255 
256         let former_arg = self.cmd.find(name).expect(INTERNAL_ERROR_MSG);
257         let usg = self.build_conflict_err_usage(matcher, conflict_ids);
258         Err(Error::argument_conflict(
259             self.cmd,
260             former_arg.to_string(),
261             conflicts,
262             usg,
263         ))
264     }
265 
build_conflict_err_usage(&self, matcher: &ArgMatcher, conflicting_keys: &[Id]) -> String266     fn build_conflict_err_usage(&self, matcher: &ArgMatcher, conflicting_keys: &[Id]) -> String {
267         let used_filtered: Vec<Id> = matcher
268             .arg_ids()
269             .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent))
270             .filter(|n| {
271                 // Filter out the args we don't want to specify.
272                 self.cmd.find(n).map_or(true, |a| !a.is_hide_set())
273             })
274             .filter(|key| !conflicting_keys.contains(key))
275             .cloned()
276             .collect();
277         let required: Vec<Id> = used_filtered
278             .iter()
279             .filter_map(|key| self.cmd.find(key))
280             .flat_map(|arg| arg.requires.iter().map(|item| &item.1))
281             .filter(|key| !used_filtered.contains(key) && !conflicting_keys.contains(key))
282             .chain(used_filtered.iter())
283             .cloned()
284             .collect();
285         Usage::new(self.cmd)
286             .required(&self.required)
287             .create_usage_with_title(&required)
288     }
289 
gather_requires(&mut self, matcher: &ArgMatcher)290     fn gather_requires(&mut self, matcher: &ArgMatcher) {
291         debug!("Validator::gather_requires");
292         for name in matcher
293             .arg_ids()
294             .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent))
295         {
296             debug!("Validator::gather_requires:iter:{:?}", name);
297             if let Some(arg) = self.cmd.find(name) {
298                 let is_relevant = |(val, req_arg): &(ArgPredicate<'_>, Id)| -> Option<Id> {
299                     let required = matcher.check_explicit(&arg.id, *val);
300                     required.then(|| req_arg.clone())
301                 };
302 
303                 for req in self.cmd.unroll_arg_requires(is_relevant, &arg.id) {
304                     self.required.insert(req);
305                 }
306             } else if let Some(g) = self.cmd.find_group(name) {
307                 debug!("Validator::gather_requires:iter:{:?}:group", name);
308                 for r in &g.requires {
309                     self.required.insert(r.clone());
310                 }
311             }
312         }
313     }
314 
validate_matched_args(&self, matcher: &ArgMatcher) -> ClapResult<()>315     fn validate_matched_args(&self, matcher: &ArgMatcher) -> ClapResult<()> {
316         debug!("Validator::validate_matched_args");
317         matcher.iter().try_for_each(|(name, ma)| {
318             debug!(
319                 "Validator::validate_matched_args:iter:{:?}: vals={:#?}",
320                 name,
321                 ma.vals_flatten()
322             );
323             if let Some(arg) = self.cmd.find(name) {
324                 self.validate_arg_num_vals(arg, ma)?;
325                 self.validate_arg_values(arg, ma)?;
326                 self.validate_arg_num_occurs(arg, ma)?;
327             }
328             Ok(())
329         })
330     }
331 
validate_arg_num_occurs(&self, a: &Arg, ma: &MatchedArg) -> ClapResult<()>332     fn validate_arg_num_occurs(&self, a: &Arg, ma: &MatchedArg) -> ClapResult<()> {
333         #![allow(deprecated)]
334         debug!(
335             "Validator::validate_arg_num_occurs: {:?}={}",
336             a.name,
337             ma.get_occurrences()
338         );
339         // Occurrence of positional argument equals to number of values rather
340         // than number of grouped values.
341         if ma.get_occurrences() > 1 && !a.is_multiple_occurrences_set() && !a.is_positional() {
342             // Not the first time, and we don't allow multiples
343             return Err(Error::unexpected_multiple_usage(
344                 self.cmd,
345                 a.to_string(),
346                 Usage::new(self.cmd)
347                     .required(&self.required)
348                     .create_usage_with_title(&[]),
349             ));
350         }
351         if let Some(max_occurs) = a.max_occurs {
352             debug!(
353                 "Validator::validate_arg_num_occurs: max_occurs set...{}",
354                 max_occurs
355             );
356             let occurs = ma.get_occurrences() as usize;
357             if occurs > max_occurs {
358                 return Err(Error::too_many_occurrences(
359                     self.cmd,
360                     a.to_string(),
361                     max_occurs,
362                     occurs,
363                     Usage::new(self.cmd)
364                         .required(&self.required)
365                         .create_usage_with_title(&[]),
366                 ));
367             }
368         }
369 
370         Ok(())
371     }
372 
validate_arg_num_vals(&self, a: &Arg, ma: &MatchedArg) -> ClapResult<()>373     fn validate_arg_num_vals(&self, a: &Arg, ma: &MatchedArg) -> ClapResult<()> {
374         debug!("Validator::validate_arg_num_vals");
375         if let Some(num) = a.num_vals {
376             let total_num = ma.num_vals();
377             debug!("Validator::validate_arg_num_vals: num_vals set...{}", num);
378             #[allow(deprecated)]
379             let should_err = if a.is_multiple_occurrences_set() {
380                 total_num % num != 0
381             } else {
382                 num != total_num
383             };
384             if should_err {
385                 debug!("Validator::validate_arg_num_vals: Sending error WrongNumberOfValues");
386                 return Err(Error::wrong_number_of_values(
387                     self.cmd,
388                     a.to_string(),
389                     num,
390                     #[allow(deprecated)]
391                     if a.is_multiple_occurrences_set() {
392                         total_num % num
393                     } else {
394                         total_num
395                     },
396                     Usage::new(self.cmd)
397                         .required(&self.required)
398                         .create_usage_with_title(&[]),
399                 ));
400             }
401         }
402         if let Some(num) = a.max_vals {
403             debug!("Validator::validate_arg_num_vals: max_vals set...{}", num);
404             if ma.num_vals() > num {
405                 debug!("Validator::validate_arg_num_vals: Sending error TooManyValues");
406                 return Err(Error::too_many_values(
407                     self.cmd,
408                     ma.raw_vals_flatten()
409                         .last()
410                         .expect(INTERNAL_ERROR_MSG)
411                         .to_str()
412                         .expect(INVALID_UTF8)
413                         .to_string(),
414                     a.to_string(),
415                     Usage::new(self.cmd)
416                         .required(&self.required)
417                         .create_usage_with_title(&[]),
418                 ));
419             }
420         }
421         let min_vals_zero = if let Some(num) = a.min_vals {
422             debug!("Validator::validate_arg_num_vals: min_vals set: {}", num);
423             if ma.num_vals() < num && num != 0 {
424                 debug!("Validator::validate_arg_num_vals: Sending error TooFewValues");
425                 return Err(Error::too_few_values(
426                     self.cmd,
427                     a.to_string(),
428                     num,
429                     ma.num_vals(),
430                     Usage::new(self.cmd)
431                         .required(&self.required)
432                         .create_usage_with_title(&[]),
433                 ));
434             }
435             num == 0
436         } else {
437             false
438         };
439         // Issue 665 (https://github.com/clap-rs/clap/issues/665)
440         // Issue 1105 (https://github.com/clap-rs/clap/issues/1105)
441         if a.is_takes_value_set() && !min_vals_zero && ma.all_val_groups_empty() {
442             return Err(Error::empty_value(
443                 self.cmd,
444                 &get_possible_values(a)
445                     .iter()
446                     .filter(|pv| !pv.is_hide_set())
447                     .map(PossibleValue::get_name)
448                     .collect::<Vec<_>>(),
449                 a.to_string(),
450             ));
451         }
452         Ok(())
453     }
454 
validate_required( &mut self, matcher: &ArgMatcher, conflicts: &mut Conflicts, ) -> ClapResult<()>455     fn validate_required(
456         &mut self,
457         matcher: &ArgMatcher,
458         conflicts: &mut Conflicts,
459     ) -> ClapResult<()> {
460         debug!("Validator::validate_required: required={:?}", self.required);
461         self.gather_requires(matcher);
462 
463         let is_exclusive_present = matcher
464             .arg_ids()
465             .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent))
466             .any(|id| {
467                 self.cmd
468                     .find(id)
469                     .map(|arg| arg.is_exclusive_set())
470                     .unwrap_or_default()
471             });
472         debug!(
473             "Validator::validate_required: is_exclusive_present={}",
474             is_exclusive_present
475         );
476 
477         for arg_or_group in self
478             .required
479             .iter()
480             .filter(|r| !matcher.check_explicit(r, ArgPredicate::IsPresent))
481         {
482             debug!("Validator::validate_required:iter:aog={:?}", arg_or_group);
483             if let Some(arg) = self.cmd.find(arg_or_group) {
484                 debug!("Validator::validate_required:iter: This is an arg");
485                 if !is_exclusive_present && !self.is_missing_required_ok(arg, matcher, conflicts) {
486                     return self.missing_required_error(matcher, vec![]);
487                 }
488             } else if let Some(group) = self.cmd.find_group(arg_or_group) {
489                 debug!("Validator::validate_required:iter: This is a group");
490                 if !self
491                     .cmd
492                     .unroll_args_in_group(&group.id)
493                     .iter()
494                     .any(|a| matcher.check_explicit(a, ArgPredicate::IsPresent))
495                 {
496                     return self.missing_required_error(matcher, vec![]);
497                 }
498             }
499         }
500 
501         // Validate the conditionally required args
502         for a in self.cmd.get_arguments() {
503             for (other, val) in &a.r_ifs {
504                 if matcher.check_explicit(other, ArgPredicate::Equals(std::ffi::OsStr::new(*val)))
505                     && !matcher.check_explicit(&a.id, ArgPredicate::IsPresent)
506                 {
507                     return self.missing_required_error(matcher, vec![a.id.clone()]);
508                 }
509             }
510 
511             let match_all = a.r_ifs_all.iter().all(|(other, val)| {
512                 matcher.check_explicit(other, ArgPredicate::Equals(std::ffi::OsStr::new(*val)))
513             });
514             if match_all
515                 && !a.r_ifs_all.is_empty()
516                 && !matcher.check_explicit(&a.id, ArgPredicate::IsPresent)
517             {
518                 return self.missing_required_error(matcher, vec![a.id.clone()]);
519             }
520         }
521 
522         self.validate_required_unless(matcher)?;
523 
524         Ok(())
525     }
526 
is_missing_required_ok( &self, a: &Arg<'help>, matcher: &ArgMatcher, conflicts: &mut Conflicts, ) -> bool527     fn is_missing_required_ok(
528         &self,
529         a: &Arg<'help>,
530         matcher: &ArgMatcher,
531         conflicts: &mut Conflicts,
532     ) -> bool {
533         debug!("Validator::is_missing_required_ok: {}", a.name);
534         let conflicts = conflicts.gather_conflicts(self.cmd, matcher, &a.id);
535         !conflicts.is_empty()
536     }
537 
validate_required_unless(&self, matcher: &ArgMatcher) -> ClapResult<()>538     fn validate_required_unless(&self, matcher: &ArgMatcher) -> ClapResult<()> {
539         debug!("Validator::validate_required_unless");
540         let failed_args: Vec<_> = self
541             .cmd
542             .get_arguments()
543             .filter(|&a| {
544                 (!a.r_unless.is_empty() || !a.r_unless_all.is_empty())
545                     && !matcher.check_explicit(&a.id, ArgPredicate::IsPresent)
546                     && self.fails_arg_required_unless(a, matcher)
547             })
548             .map(|a| a.id.clone())
549             .collect();
550         if failed_args.is_empty() {
551             Ok(())
552         } else {
553             self.missing_required_error(matcher, failed_args)
554         }
555     }
556 
557     // Failing a required unless means, the arg's "unless" wasn't present, and neither were they
fails_arg_required_unless(&self, a: &Arg<'help>, matcher: &ArgMatcher) -> bool558     fn fails_arg_required_unless(&self, a: &Arg<'help>, matcher: &ArgMatcher) -> bool {
559         debug!("Validator::fails_arg_required_unless: a={:?}", a.name);
560         let exists = |id| matcher.check_explicit(id, ArgPredicate::IsPresent);
561 
562         (a.r_unless_all.is_empty() || !a.r_unless_all.iter().all(exists))
563             && !a.r_unless.iter().any(exists)
564     }
565 
566     // `incl`: an arg to include in the error even if not used
missing_required_error(&self, matcher: &ArgMatcher, incl: Vec<Id>) -> ClapResult<()>567     fn missing_required_error(&self, matcher: &ArgMatcher, incl: Vec<Id>) -> ClapResult<()> {
568         debug!("Validator::missing_required_error; incl={:?}", incl);
569         debug!(
570             "Validator::missing_required_error: reqs={:?}",
571             self.required
572         );
573 
574         let usg = Usage::new(self.cmd).required(&self.required);
575 
576         let req_args = usg
577             .get_required_usage_from(&incl, Some(matcher), true)
578             .into_iter()
579             .collect::<Vec<_>>();
580 
581         debug!(
582             "Validator::missing_required_error: req_args={:#?}",
583             req_args
584         );
585 
586         let used: Vec<Id> = matcher
587             .arg_ids()
588             .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent))
589             .filter(|n| {
590                 // Filter out the args we don't want to specify.
591                 self.cmd.find(n).map_or(true, |a| !a.is_hide_set())
592             })
593             .cloned()
594             .chain(incl)
595             .collect();
596 
597         Err(Error::missing_required_argument(
598             self.cmd,
599             req_args,
600             usg.create_usage_with_title(&used),
601         ))
602     }
603 }
604 
605 #[derive(Default, Clone, Debug)]
606 struct Conflicts {
607     potential: std::collections::HashMap<Id, Vec<Id>>,
608 }
609 
610 impl Conflicts {
new() -> Self611     fn new() -> Self {
612         Self::default()
613     }
614 
gather_conflicts(&mut self, cmd: &Command, matcher: &ArgMatcher, arg_id: &Id) -> Vec<Id>615     fn gather_conflicts(&mut self, cmd: &Command, matcher: &ArgMatcher, arg_id: &Id) -> Vec<Id> {
616         debug!("Conflicts::gather_conflicts: arg={:?}", arg_id);
617         let mut conflicts = Vec::new();
618         for other_arg_id in matcher
619             .arg_ids()
620             .filter(|arg_id| matcher.check_explicit(arg_id, ArgPredicate::IsPresent))
621         {
622             if arg_id == other_arg_id {
623                 continue;
624             }
625 
626             if self
627                 .gather_direct_conflicts(cmd, arg_id)
628                 .contains(other_arg_id)
629             {
630                 conflicts.push(other_arg_id.clone());
631             }
632             if self
633                 .gather_direct_conflicts(cmd, other_arg_id)
634                 .contains(arg_id)
635             {
636                 conflicts.push(other_arg_id.clone());
637             }
638         }
639         debug!("Conflicts::gather_conflicts: conflicts={:?}", conflicts);
640         conflicts
641     }
642 
gather_direct_conflicts(&mut self, cmd: &Command, arg_id: &Id) -> &[Id]643     fn gather_direct_conflicts(&mut self, cmd: &Command, arg_id: &Id) -> &[Id] {
644         self.potential.entry(arg_id.clone()).or_insert_with(|| {
645             let conf = if let Some(arg) = cmd.find(arg_id) {
646                 let mut conf = arg.blacklist.clone();
647                 for group_id in cmd.groups_for_arg(arg_id) {
648                     let group = cmd.find_group(&group_id).expect(INTERNAL_ERROR_MSG);
649                     conf.extend(group.conflicts.iter().cloned());
650                     if !group.multiple {
651                         for member_id in &group.args {
652                             if member_id != arg_id {
653                                 conf.push(member_id.clone());
654                             }
655                         }
656                     }
657                 }
658 
659                 // Overrides are implicitly conflicts
660                 conf.extend(arg.overrides.iter().cloned());
661 
662                 conf
663             } else if let Some(group) = cmd.find_group(arg_id) {
664                 group.conflicts.clone()
665             } else {
666                 debug_assert!(false, "id={:?} is unknown", arg_id);
667                 Vec::new()
668             };
669             debug!(
670                 "Conflicts::gather_direct_conflicts id={:?}, conflicts={:?}",
671                 arg_id, conf
672             );
673             conf
674         })
675     }
676 }
677 
get_possible_values<'help>(a: &Arg<'help>) -> Vec<PossibleValue<'help>>678 fn get_possible_values<'help>(a: &Arg<'help>) -> Vec<PossibleValue<'help>> {
679     #![allow(deprecated)]
680     if !a.is_takes_value_set() {
681         vec![]
682     } else if let Some(pvs) = a.get_possible_values() {
683         // Check old first in case the user explicitly set possible values and the derive inferred
684         // a `ValueParser` with some.
685         pvs.to_vec()
686     } else {
687         a.get_value_parser()
688             .possible_values()
689             .map(|pvs| pvs.collect())
690             .unwrap_or_default()
691     }
692 }
693