Update std::io::Error::downcast return type

and update its doc according to decision made by rust libs-api team.

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
Jiahao XU 2024-01-19 09:26:56 +11:00
parent c485ee7147
commit baa2cf5ea6
No known key found for this signature in database
GPG Key ID: D7D0DA2A5FE7AF8B
2 changed files with 33 additions and 7 deletions

View File

@ -816,12 +816,12 @@ impl Error {
} }
} }
/// Attempt to downgrade the inner error to `E` if any. /// Attempt to downcast the inner error to `E` if any.
/// ///
/// If this [`Error`] was constructed via [`new`] then this function will /// If this [`Error`] was constructed via [`new`] then this function will
/// attempt to perform downgrade on it, otherwise it will return [`Err`]. /// attempt to perform downgrade on it, otherwise it will return [`Err`].
/// ///
/// If downgrade succeeds, it will return [`Ok`], otherwise it will also /// If the downcast succeeds, it will return [`Ok`], otherwise it will also
/// return [`Err`]. /// return [`Err`].
/// ///
/// [`new`]: Error::new /// [`new`]: Error::new
@ -852,13 +852,39 @@ impl Error {
/// impl From<io::Error> for E { /// impl From<io::Error> for E {
/// fn from(err: io::Error) -> E { /// fn from(err: io::Error) -> E {
/// err.downcast::<E>() /// err.downcast::<E>()
/// .map(|b| *b)
/// .unwrap_or_else(E::Io) /// .unwrap_or_else(E::Io)
/// } /// }
/// } /// }
///
/// impl From<E> for io::Error {
/// fn from(err: E) -> io::Error {
/// match err {
/// E::Io(io_error) => io_error,
/// e => io::Error::new(io::ErrorKind::Other, e),
/// }
/// }
/// }
///
/// # fn main() {
/// let e = E::SomeOtherVariant;
/// // Convert it to an io::Error
/// let io_error = io::Error::from(e);
/// // Cast it back to the original variant
/// let e = E::from(io_error);
/// assert!(matches!(e, E::SomeOtherVariant));
///
/// let io_error = io::Error::from(io::ErrorKind::AlreadyExists);
/// // Convert it to E
/// let e = E::from(io_error);
/// // Cast it back to the original variant
/// let io_error = io::Error::from(e);
/// assert_eq!(io_error.kind(), io::ErrorKind::AlreadyExists);
/// assert!(io_error.get_ref().is_none());
/// assert!(io_error.raw_os_error().is_none());
/// # }
/// ``` /// ```
#[unstable(feature = "io_error_downcast", issue = "99262")] #[unstable(feature = "io_error_downcast", issue = "99262")]
pub fn downcast<E>(self) -> result::Result<Box<E>, Self> pub fn downcast<E>(self) -> result::Result<E, Self>
where where
E: error::Error + Send + Sync + 'static, E: error::Error + Send + Sync + 'static,
{ {
@ -872,7 +898,7 @@ impl Error {
// And the compiler should be able to eliminate the branch // And the compiler should be able to eliminate the branch
// that produces `Err` here since b.error.is::<E>() // that produces `Err` here since b.error.is::<E>()
// returns true. // returns true.
Ok(res.unwrap()) Ok(*res.unwrap())
} }
repr_data => Err(Self { repr: Repr::new(repr_data) }), repr_data => Err(Self { repr: Repr::new(repr_data) }),
} }

View File

@ -157,7 +157,7 @@ impl error::Error for E {}
fn test_std_io_error_downcast() { fn test_std_io_error_downcast() {
// Case 1: custom error, downcast succeeds // Case 1: custom error, downcast succeeds
let io_error = Error::new(ErrorKind::Other, Bojji(true)); let io_error = Error::new(ErrorKind::Other, Bojji(true));
let e: Box<Bojji> = io_error.downcast().unwrap(); let e: Bojji = io_error.downcast().unwrap();
assert!(e.0); assert!(e.0);
// Case 2: custom error, downcast fails // Case 2: custom error, downcast fails
@ -166,7 +166,7 @@ fn test_std_io_error_downcast() {
// ensures that the custom error is intact // ensures that the custom error is intact
assert_eq!(ErrorKind::Other, io_error.kind()); assert_eq!(ErrorKind::Other, io_error.kind());
let e: Box<Bojji> = io_error.downcast().unwrap(); let e: Bojji = io_error.downcast().unwrap();
assert!(e.0); assert!(e.0);
// Case 3: os error // Case 3: os error