Skip to main content

clap_builder/parser/
error.rs

1use 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]
7pub 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
23impl MatchesError {
24    #[cfg_attr(debug_assertions, track_caller)]
25    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
36impl std::error::Error for MatchesError {}
37
38impl std::fmt::Display for MatchesError {
39    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!(
49                    f,
50                    "Unknown argument or group id.  Make sure you are using the argument id and not the short or long flags"
51                )
52            }
53        }
54    }
55}
56
57#[test]
58fn check_auto_traits() {
59    static_assertions::assert_impl_all!(
60        MatchesError: Send,
61        Sync,
62        std::panic::RefUnwindSafe,
63        std::panic::UnwindSafe,
64        Unpin
65    );
66}