1 use crate::util::AnyValueId;
2 
3 /// Violation of [`ArgMatches`][crate::ArgMatches] assumptions
4 #[derive(Clone, Debug)]
5 #[allow(missing_copy_implementations)] // We might add non-Copy types in the future
6 #[non_exhaustive]
7 pub enum MatchesError {
8     /// Failed to downcast `AnyValue` to the specified type
9     #[non_exhaustive]
10     Downcast {
11         /// Type for value stored in [`ArgMatches`][crate::ArgMatches]
12         actual: AnyValueId,
13         /// The target type to downcast to
14         expected: AnyValueId,
15     },
16     /// Argument not defined in [`Command`][crate::Command]
17     #[non_exhaustive]
18     UnknownArgument {
19         // Missing `id` but blocked on a public id type which will hopefully come with `unstable-v4`
20     },
21 }
22 
23 impl MatchesError {
24     #[cfg_attr(debug_assertions, track_caller)]
unwrap<T>(id: &str, r: Result<T, MatchesError>) -> T25     pub(crate) fn unwrap<T>(id: &str, r: Result<T, MatchesError>) -> T {
26         let err = match r {
27             Ok(t) => {
28                 return t;
29             }
30             Err(err) => err,
31         };
32         panic!("Mismatch between definition and access of `{id}`. {err}",)
33     }
34 }
35 
36 impl std::error::Error for MatchesError {}
37 
38 impl std::fmt::Display for MatchesError {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result39     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
40         match self {
41             Self::Downcast { actual, expected } => {
42                 writeln!(
43                     f,
44                     "Could not downcast to {expected:?}, need to downcast to {actual:?}"
45                 )
46             }
47             Self::UnknownArgument {} => {
48                 writeln!(f, "Unknown argument or group id.  Make sure you are using the argument id and not the short or long flags")
49             }
50         }
51     }
52 }
53 
54 #[test]
check_auto_traits()55 fn check_auto_traits() {
56     static_assertions::assert_impl_all!(
57         MatchesError: Send,
58         Sync,
59         std::panic::RefUnwindSafe,
60         std::panic::UnwindSafe,
61         Unpin
62     );
63 }
64