From 8a9d48d97cda01bb1d769d9d98c38cd50218d6c7 Mon Sep 17 00:00:00 2001 From: Botahamec Date: Tue, 8 Aug 2023 18:41:14 -0400 Subject: Allow conversion from Option to Result --- src/result.rs | 7 +++++++ src/unexpected.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) (limited to 'src') diff --git a/src/result.rs b/src/result.rs index 7afceed..25392c8 100644 --- a/src/result.rs +++ b/src/result.rs @@ -6,6 +6,7 @@ use crate::{unexpected::Errorable, RawUnexpected}; mod sealed { pub trait Sealed {} impl Sealed for Result {} + impl Sealed for Option {} } use sealed::Sealed; @@ -71,6 +72,12 @@ impl ResultErrorExt for Result { } } +impl ResultErrorExt for Option { + fn unexpect(self) -> Result { + self.ok_or_else(RawUnexpected::none) + } +} + /// Provides [`Result::unexpect_msg`] /// /// [`Result::unexpect_msg`]: `ResultMsgExt::unexpect_msg` diff --git a/src/unexpected.rs b/src/unexpected.rs index 321973f..6538b96 100644 --- a/src/unexpected.rs +++ b/src/unexpected.rs @@ -11,6 +11,7 @@ impl Errorable for T {} #[derive(Debug)] enum ErrorTy { + None, Message(Box), #[cfg(feature = "std")] Error(Box), @@ -30,6 +31,7 @@ pub struct RawUnexpected { impl Display for RawUnexpected { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self.internal { + ErrorTy::None => Display::fmt("Called `unexpect` on a `None` value", f), ErrorTy::Message(m) => Display::fmt(&m, f), #[cfg(feature = "std")] ErrorTy::Error(e) => Display::fmt(&e, f), @@ -60,6 +62,7 @@ impl RawUnexpected { /// let x = RawUnexpected::new(core::fmt::Error); /// ``` #[cfg(feature = "std")] + #[must_use] pub fn new(error: E) -> Self { Self { internal: ErrorTy::Error(Box::new(error)), @@ -80,12 +83,34 @@ impl RawUnexpected { /// /// let x = RawUnexpected::msg("failed"); /// ``` + #[must_use] pub fn msg(error: E) -> Self { Self { internal: ErrorTy::Message(Box::new(error)), } } + /// Create a new `RawUnexpected` that is simply empty. + /// + /// This is used for converting an [`Option`] to a + /// [`Result Self { + Self { + internal: ErrorTy::None, + } + } + /// Get the original error. /// /// This will return `None` if `self` was created using @@ -108,6 +133,7 @@ impl RawUnexpected { #[cfg(feature = "std")] pub fn source(&self) -> Option<&(dyn Error + 'static)> { match &self.internal { + ErrorTy::None => None, ErrorTy::Message(_) => None, #[cfg(feature = "std")] ErrorTy::Error(e) => Some(&**e), @@ -138,6 +164,7 @@ impl UnexpectedError { /// let x = UnexpectedError::new(core::fmt::Error); /// ``` #[cfg(feature = "std")] + #[must_use] pub fn new(error: E) -> Self { Self(RawUnexpected::new(error)) } @@ -156,9 +183,29 @@ impl UnexpectedError { /// /// let x = UnexpectedError::msg("failed"); /// ``` + #[must_use] pub fn msg(error: E) -> Self { Self(RawUnexpected::msg(error)) } + + /// Create a new `RawUnexpected` that is simply empty. + /// + /// This is used for converting an [`Option`] to a + /// [`Result Self { + Self(RawUnexpected::none()) + } } impl From for UnexpectedError { -- cgit v1.2.3