Skip to content

Commit e0ea0c2

Browse files
committed
Add new unstable API Error::try_downgrade_inner
Signed-off-by: Jiahao XU <[email protected]>
1 parent 1713e25 commit e0ea0c2

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

library/std/src/io/error.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,63 @@ impl Error {
795795
}
796796
}
797797

798+
/// Attempt to downgrade the inner error to `E` if any.
799+
///
800+
/// If this [`Error`] was constructed via [`new`] then this function will
801+
/// attempt to perform downgrade on it, otherwise it will return [`Err`].
802+
///
803+
/// If downgrade succeeds, it will return [`Ok`], otherwise it will also
804+
/// return [`Err`].
805+
///
806+
/// [`new`]: Error::new
807+
///
808+
/// # Examples
809+
///
810+
/// ```
811+
/// #![feature(io_error_try_downcast_inner)]
812+
///
813+
/// use std::fmt;
814+
/// use std::io;
815+
/// use std::error::Error;
816+
///
817+
/// #[derive(Debug)]
818+
/// enum E {
819+
/// Io(io::Error),
820+
/// SomeOtherVariant,
821+
/// }
822+
///
823+
/// impl fmt::Display for E {
824+
/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
825+
/// todo!()
826+
/// }
827+
/// }
828+
/// impl Error for E {}
829+
///
830+
/// impl From<io::Error> for E {
831+
/// fn from(err: io::Error) -> E {
832+
/// err.try_downcast_inner::<E>()
833+
/// .map(|b| *b)
834+
/// .unwrap_or_else(E::Io)
835+
/// }
836+
/// }
837+
/// ```
838+
#[unstable(feature = "io_error_try_downcast_inner", issue = "none")]
839+
pub fn try_downcast_inner<E>(self) -> result::Result<Box<E>, Self>
840+
where
841+
E: error::Error + Send + Sync + 'static,
842+
{
843+
match self.repr.into_data() {
844+
ErrorData::Custom(b) if b.error.is::<E>() => {
845+
let res = (*b).error.downcast::<E>();
846+
847+
// Safety: b.error.is::<E>() returns true,
848+
// which means that res must be Ok(e).
849+
Ok(unsafe { res.unwrap_unchecked() })
850+
}
851+
repr_data => Err(Self { repr: Repr::new(repr_data) }),
852+
}
853+
}
854+
798855
/// Returns the corresponding [`ErrorKind`] for this error.
799856
///
800857
/// # Examples

0 commit comments

Comments
 (0)