playdate_sys/sys/error/
mod.rs

1//! Typed API errors.
2
3use core::any::Any;
4use core::convert::Infallible;
5use core::fmt;
6use core::error::Error as CoreError;
7
8use crate::ffi::Utf8Error;
9use alloc::ffi::NulError;
10use alloc::string::FromUtf8Error;
11pub use null::*;
12mod null;
13
14
15#[derive(Debug)]
16pub enum Error<T = ()> {
17	Api(T),
18	Utf8(Utf8Error),
19	FromUtf8(FromUtf8Error),
20	CStr(NulError),
21	NullPtr(null::NullPtrError),
22	#[cfg(feature = "error-ctx")]
23	NullPtrCtx(null::ctx::NullPtrError),
24}
25
26impl<T: fmt::Display> fmt::Display for Error<T> {
27	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28		match &self {
29			Error::Api(err) => err.fmt(f),
30			Error::Utf8(err) => err.fmt(f),
31			Error::FromUtf8(err) => err.fmt(f),
32			Error::CStr(err) => err.fmt(f),
33			Error::NullPtr(err) => err.fmt(f),
34			#[cfg(feature = "error-ctx")]
35			Error::NullPtrCtx(err) => err.fmt(f),
36		}
37	}
38}
39
40impl<T> Error<T> {
41	pub fn from_err<E>(error: Error<E>) -> Self
42		where T: From<E> {
43		match error {
44			Error::Api(err) => Error::Api(err.into()),
45			Error::Utf8(err) => Error::Utf8(err),
46			Error::FromUtf8(err) => Error::FromUtf8(err),
47			Error::CStr(err) => Error::CStr(err),
48			Error::NullPtr(err) => Error::NullPtr(err),
49			#[cfg(feature = "error-ctx")]
50			Error::NullPtrCtx(err) => Error::NullPtrCtx(err),
51		}
52	}
53}
54
55
56impl<T> From<Utf8Error> for Error<T> {
57	fn from(error: Utf8Error) -> Self { Self::Utf8(error) }
58}
59
60impl<T> From<FromUtf8Error> for Error<T> {
61	fn from(error: FromUtf8Error) -> Self { Self::FromUtf8(error) }
62}
63
64impl<T> From<null::NullPtrError> for Error<T> {
65	fn from(error: null::NullPtrError) -> Self { Self::NullPtr(error) }
66}
67
68impl<T> From<NulError> for Error<T> {
69	fn from(error: NulError) -> Self { Self::CStr(error) }
70}
71
72impl<T> From<Infallible> for Error<T> {
73	fn from(_: Infallible) -> Self { unreachable!() }
74}
75
76#[cfg(feature = "error-ctx")]
77impl<T> From<null::ctx::NullPtrError> for Error<T> {
78	fn from(error: null::ctx::NullPtrError) -> Self { Self::NullPtrCtx(error) }
79}
80
81
82impl<T: Any> CoreError for Error<T> where T: fmt::Display + fmt::Debug {
83	fn source(&self) -> Option<&(dyn CoreError + 'static)> {
84		match self {
85			Error::Utf8(err) => Some(err),
86			Error::FromUtf8(err) => Some(err),
87			Error::CStr(err) => Some(err),
88			Error::NullPtr(err) => Some(err),
89			#[cfg(feature = "error-ctx")]
90			Error::NullPtrCtx(err) => Some(err),
91			Error::Api(err) => (err as &dyn Any).downcast_ref::<&dyn CoreError>().copied(),
92		}
93	}
94
95	// Removed text from str to do not store this in output binary.
96	/// `description()` is deprecated; use `Display`
97	fn description(&self) -> &str { "" }
98}