summaryrefslogtreecommitdiff
path: root/src/unexpected.rs
diff options
context:
space:
mode:
authorBotahamec <botahamec@outlook.com>2022-10-22 21:42:00 -0400
committerBotahamec <botahamec@outlook.com>2022-10-22 21:42:00 -0400
commitbe5c361bf817483467a14c4b907c90d10f512f56 (patch)
treea7f94d0b0d6e8431b1b5ef3918de8734f101bc9b /src/unexpected.rs
parent912b7aae3029dbf0364f951944ac4ecb1da83178 (diff)
Created UnexpectedError
Diffstat (limited to 'src/unexpected.rs')
-rw-r--r--src/unexpected.rs86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/unexpected.rs b/src/unexpected.rs
new file mode 100644
index 0000000..6e5548b
--- /dev/null
+++ b/src/unexpected.rs
@@ -0,0 +1,86 @@
+use core::fmt::{self, Debug, Display};
+
+#[cfg(not(feature = "std"))]
+use alloc::boxed::Box;
+
+#[cfg(feature = "std")]
+use std::error::Error;
+
+pub trait Errorable: Display + Debug {}
+impl<T: Display + Debug> Errorable for T {}
+
+#[derive(Debug)]
+#[non_exhaustive]
+enum ErrorTy {
+ Message(Box<dyn Errorable + 'static>),
+ #[cfg(feature = "std")]
+ Error(Box<dyn Error + 'static>),
+}
+
+#[derive(Debug)]
+pub struct UnexpectedError {
+ internal: ErrorTy,
+}
+
+impl Display for UnexpectedError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match &self.internal {
+ ErrorTy::Message(m) => Display::fmt(&m, f),
+ #[cfg(feature = "std")]
+ ErrorTy::Error(e) => Display::fmt(&e, f),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl Error for UnexpectedError {
+ fn source(&self) -> Option<&(dyn Error + 'static)> {
+ match &self.internal {
+ ErrorTy::Message(_) => None,
+ #[cfg(feature = "std")]
+ ErrorTy::Error(e) => Some(&**e),
+ }
+ }
+}
+
+impl UnexpectedError {
+ /// Create a new `UnexpectedError` from any [`Error`] type.
+ ///
+ /// The error must be `'static` so that the `UnexpectedError` will be too.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// use exun::*;
+ ///
+ /// let err = UnexpectedError::new(core::fmt::Error);
+ /// ```
+ #[cfg(feature = "std")]
+ pub fn new<E: Error + 'static>(e: E) -> Self {
+ Self {
+ internal: ErrorTy::Error(Box::new(e)),
+ }
+ }
+
+ /// Create an error message from a printable error message.
+ ///
+ /// If the argument implements [`Error`], prefer [`UnexpectedError::new`]
+ /// instead, which preserves the source.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// use exun::*;
+ ///
+ /// let err = UnexpectedError::msg("failed");
+ /// ```
+ pub fn msg<E: Errorable + 'static>(e: E) -> Self {
+ Self {
+ internal: ErrorTy::Message(Box::new(e)),
+ }
+ }
+}