use std::error::Error as StdError;
#[derive(Debug, Copy, Clone, PartialEq, Eq, thiserror::Error)]
pub enum Error {
#[error("invalid parameter or other input")]
InvalidInput,
#[error("i/o error encountered")]
Io,
#[error("timed out")]
Timeout,
#[error("an error occurred and the connection must be re-established before retrying")]
ConnectionClosed,
#[error("received a response which was invalid in some way")]
InvalidResponse,
}
impl From<hyper::Error> for Error {
fn from(e: hyper::Error) -> Self {
if io_error(&e) {
Error::Io
} else if e.is_timeout() {
Error::Timeout
} else if e.is_parse() || e.is_user() {
Error::InvalidInput
} else if e.is_parse_status() || e.is_parse_version_h2() {
Error::InvalidResponse
} else {
Error::ConnectionClosed
}
}
}
fn io_error(e: &hyper::Error) -> bool {
let mut e = e as &dyn StdError;
loop {
match e.source() {
None => return false,
Some(source) => {
let io = source.downcast_ref::<std::io::Error>();
if io.is_some() {
return true;
}
e = source;
}
}
}
}