Add support for downcasting response errors

This commit is contained in:
Armin Ronacher 2019-07-18 11:40:42 +02:00
parent d03296237e
commit 72190a46ce
1 changed files with 22 additions and 0 deletions

View File

@ -4,6 +4,7 @@ use std::io::Write;
use std::str::Utf8Error; use std::str::Utf8Error;
use std::string::FromUtf8Error; use std::string::FromUtf8Error;
use std::{fmt, io, result}; use std::{fmt, io, result};
use std::any::TypeId;
pub use actix_threadpool::BlockingError; pub use actix_threadpool::BlockingError;
use actix_utils::timeout::TimeoutError; use actix_utils::timeout::TimeoutError;
@ -51,6 +52,11 @@ impl Error {
pub fn as_response_error(&self) -> &dyn ResponseError { pub fn as_response_error(&self) -> &dyn ResponseError {
self.cause.as_ref() self.cause.as_ref()
} }
/// Similar to `as_response_error` but downcasts.
pub fn as_error<T: ResponseError + 'static>(&self) -> Option<&T> {
ResponseError::downcast_ref(self.cause.as_ref())
}
} }
/// Error that can be converted to `Response` /// Error that can be converted to `Response`
@ -73,6 +79,22 @@ pub trait ResponseError: fmt::Debug + fmt::Display {
); );
resp.set_body(Body::from(buf)) resp.set_body(Body::from(buf))
} }
#[doc(hidden)]
fn __private_get_type_id__(&self) -> TypeId where Self: 'static {
TypeId::of::<Self>()
}
}
impl ResponseError + 'static {
/// Downcasts a response error to a specific type.
pub fn downcast_ref<T: ResponseError + 'static>(&self) -> Option<&T> {
if self.__private_get_type_id__() == TypeId::of::<T>() {
unsafe { Some(&*(self as *const ResponseError as *const T)) }
} else {
None
}
}
} }
impl fmt::Display for Error { impl fmt::Display for Error {