From aba1ba7b6d9f46121df4301b1601dd827f8c654d Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Sat, 18 Jun 2022 18:02:42 +1000 Subject: [PATCH] Manually impl `From for BinstallError` so that if the `io::Error` wraps a `BinstallError`, we would just unwrap it and return the inner `BinstallError`. Otherwise, just wrap the `io::Error` in a `BinstallError`. Signed-off-by: Jiahao XU --- src/errors.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/errors.rs b/src/errors.rs index 070c91ce..7ffc20e3 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -75,7 +75,7 @@ pub enum BinstallError { /// - Exit: 74 #[error(transparent)] #[diagnostic(severity(error), code(binstall::io))] - Io(#[from] std::io::Error), + Io(std::io::Error), /// An error interacting with the crates.io API. /// @@ -231,3 +231,23 @@ impl Termination for BinstallError { code } } + +impl From for BinstallError { + fn from(err: std::io::Error) -> Self { + let is_inner_binstall_err = err + .get_ref() + .map(|e| e.is::()) + .unwrap_or_default(); + + if is_inner_binstall_err { + let inner = err + .into_inner() + .expect("err.get_ref() returns Some, so err.into_inner() should als return Some"); + *inner + .downcast() + .expect("The inner err is tested to be BinstallError") + } else { + BinstallError::Io(err) + } + } +}