1 use crate::util::Id;
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: super::AnyValueId,
13 /// The target type to downcast to
14 expected: super::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 #[track_caller]
unwrap<T>(id: &Id, r: Result<T, MatchesError>) -> T25 pub(crate) fn unwrap<T>(id: &Id, r: Result<T, MatchesError>) -> T {
26 let err = match r {
27 Ok(t) => {
28 return t;
29 }
30 Err(err) => err,
31 };
32 panic!(
33 "Mismatch between definition and access of `{:?}`. {}",
34 id, err
35 )
36 }
37 }
38
39 impl std::error::Error for MatchesError {}
40
41 impl std::fmt::Display for MatchesError {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result42 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
43 match self {
44 Self::Downcast { actual, expected } => {
45 writeln!(
46 f,
47 "Could not downcast to {:?}, need to downcast to {:?}",
48 expected, actual
49 )
50 }
51 Self::UnknownArgument {} => {
52 writeln!(f, "Unknown argument or group id. Make sure you are using the argument id and not the short or long flags")
53 }
54 }
55 }
56 }
57
58 #[test]
check_auto_traits()59 fn check_auto_traits() {
60 static_assertions::assert_impl_all!(
61 MatchesError: Send,
62 Sync,
63 std::panic::RefUnwindSafe,
64 std::panic::UnwindSafe,
65 Unpin
66 );
67 }
68