119625d8cSopenharmony_ci/// Violation of [`ArgMatches`][crate::ArgMatches] assumptions
219625d8cSopenharmony_ci#[derive(Clone, Debug)]
319625d8cSopenharmony_ci#[allow(missing_copy_implementations)] // We might add non-Copy types in the future
419625d8cSopenharmony_ci#[non_exhaustive]
519625d8cSopenharmony_cipub enum MatchesError {
619625d8cSopenharmony_ci    /// Failed to downcast `AnyValue` to the specified type
719625d8cSopenharmony_ci    #[non_exhaustive]
819625d8cSopenharmony_ci    Downcast {
919625d8cSopenharmony_ci        /// Type for value stored in [`ArgMatches`][crate::ArgMatches]
1019625d8cSopenharmony_ci        actual: super::AnyValueId,
1119625d8cSopenharmony_ci        /// The target type to downcast to
1219625d8cSopenharmony_ci        expected: super::AnyValueId,
1319625d8cSopenharmony_ci    },
1419625d8cSopenharmony_ci    /// Argument not defined in [`Command`][crate::Command]
1519625d8cSopenharmony_ci    #[non_exhaustive]
1619625d8cSopenharmony_ci    UnknownArgument {
1719625d8cSopenharmony_ci        // Missing `id` but blocked on a public id type which will hopefully come with `unstable-v4`
1819625d8cSopenharmony_ci    },
1919625d8cSopenharmony_ci}
2019625d8cSopenharmony_ci
2119625d8cSopenharmony_ciimpl MatchesError {
2219625d8cSopenharmony_ci    #[cfg_attr(debug_assertions, track_caller)]
2319625d8cSopenharmony_ci    pub(crate) fn unwrap<T>(id: &str, r: Result<T, MatchesError>) -> T {
2419625d8cSopenharmony_ci        let err = match r {
2519625d8cSopenharmony_ci            Ok(t) => {
2619625d8cSopenharmony_ci                return t;
2719625d8cSopenharmony_ci            }
2819625d8cSopenharmony_ci            Err(err) => err,
2919625d8cSopenharmony_ci        };
3019625d8cSopenharmony_ci        panic!("Mismatch between definition and access of `{id}`. {err}",)
3119625d8cSopenharmony_ci    }
3219625d8cSopenharmony_ci}
3319625d8cSopenharmony_ci
3419625d8cSopenharmony_ciimpl std::error::Error for MatchesError {}
3519625d8cSopenharmony_ci
3619625d8cSopenharmony_ciimpl std::fmt::Display for MatchesError {
3719625d8cSopenharmony_ci    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
3819625d8cSopenharmony_ci        match self {
3919625d8cSopenharmony_ci            Self::Downcast { actual, expected } => {
4019625d8cSopenharmony_ci                writeln!(
4119625d8cSopenharmony_ci                    f,
4219625d8cSopenharmony_ci                    "Could not downcast to {expected:?}, need to downcast to {actual:?}"
4319625d8cSopenharmony_ci                )
4419625d8cSopenharmony_ci            }
4519625d8cSopenharmony_ci            Self::UnknownArgument {} => {
4619625d8cSopenharmony_ci                writeln!(f, "Unknown argument or group id.  Make sure you are using the argument id and not the short or long flags")
4719625d8cSopenharmony_ci            }
4819625d8cSopenharmony_ci        }
4919625d8cSopenharmony_ci    }
5019625d8cSopenharmony_ci}
5119625d8cSopenharmony_ci
5219625d8cSopenharmony_ci#[test]
5319625d8cSopenharmony_cifn check_auto_traits() {
5419625d8cSopenharmony_ci    static_assertions::assert_impl_all!(
5519625d8cSopenharmony_ci        MatchesError: Send,
5619625d8cSopenharmony_ci        Sync,
5719625d8cSopenharmony_ci        std::panic::RefUnwindSafe,
5819625d8cSopenharmony_ci        std::panic::UnwindSafe,
5919625d8cSopenharmony_ci        Unpin
6019625d8cSopenharmony_ci    );
6119625d8cSopenharmony_ci}
62