diff options
| author | Jiahao XU <Jiahao_XU@outlook.com> | 2022-06-22 22:43:54 +1000 |
|---|---|---|
| committer | Jiahao XU <Jiahao_XU@outlook.com> | 2022-06-22 22:44:30 +1000 |
| commit | e0ea0c25341a34bbaa96a8173096e7713d472131 (patch) | |
| tree | 9ed2d0ebe234281fe8e9883f67466165d9ee9ad6 | |
| parent | 1713e25a411c3854e85baa5fe076d5e3e8cffe35 (diff) | |
| download | rust-e0ea0c25341a34bbaa96a8173096e7713d472131.tar.gz rust-e0ea0c25341a34bbaa96a8173096e7713d472131.zip | |
Add new unstable API `Error::try_downgrade_inner`
Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
| -rw-r--r-- | library/std/src/io/error.rs | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 4a50e647c64..b1931a52290 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -795,6 +795,63 @@ impl Error { } } + /// Attempt to downgrade the inner error to `E` if any. + /// + /// If this [`Error`] was constructed via [`new`] then this function will + /// attempt to perform downgrade on it, otherwise it will return [`Err`]. + /// + /// If downgrade succeeds, it will return [`Ok`], otherwise it will also + /// return [`Err`]. + /// + /// [`new`]: Error::new + /// + /// # Examples + /// + /// ``` + /// #![feature(io_error_try_downcast_inner)] + /// + /// use std::fmt; + /// use std::io; + /// use std::error::Error; + /// + /// #[derive(Debug)] + /// enum E { + /// Io(io::Error), + /// SomeOtherVariant, + /// } + /// + /// impl fmt::Display for E { + /// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + /// todo!() + /// } + /// } + /// impl Error for E {} + /// + /// impl From<io::Error> for E { + /// fn from(err: io::Error) -> E { + /// err.try_downcast_inner::<E>() + /// .map(|b| *b) + /// .unwrap_or_else(E::Io) + /// } + /// } + /// ``` + #[unstable(feature = "io_error_try_downcast_inner", issue = "none")] + pub fn try_downcast_inner<E>(self) -> result::Result<Box<E>, Self> + where + E: error::Error + Send + Sync + 'static, + { + match self.repr.into_data() { + ErrorData::Custom(b) if b.error.is::<E>() => { + let res = (*b).error.downcast::<E>(); + + // Safety: b.error.is::<E>() returns true, + // which means that res must be Ok(e). + Ok(unsafe { res.unwrap_unchecked() }) + } + repr_data => Err(Self { repr: Repr::new(repr_data) }), + } + } + /// Returns the corresponding [`ErrorKind`] for this error. /// /// # Examples |
