use failure::{Backtrace, Context, Fail};
use std::{fmt, result};
pub type Result<T> = result::Result<T, Error>;
#[derive(Debug)]
pub struct Error {
context: Context<ErrType>,
}
impl Error {
pub fn kind(&self) -> &ErrType {
self.context.get_context()
}
pub(crate) fn invalid_parse<T: AsRef<str>>(unk: T) -> Error {
Error::from(ErrType::InvalidParse(unk.as_ref().to_string()))
}
pub(crate) fn invalid_path<T: AsRef<str>>(unk: T) -> Error {
Error::from(ErrType::InvalidFile(unk.as_ref().to_string()))
}
pub(crate) fn invalid_serde<T: AsRef<str>>(unk: T) -> Error {
Error::from(ErrType::InvalidSerde(unk.as_ref().to_string()))
}
pub(crate) fn invalid_code(code: i32, message: String) -> Error {
Error::from(ErrType::InvalidCode { code, message })
}
pub(crate) fn invalid_request<T: AsRef<str>>(unk: T) -> Error {
Error::from(ErrType::InvalidRequest(unk.as_ref().to_string()))
}
pub(crate) fn invalid_parameter(message: String) -> Error {
Error::from(ErrType::InvalidParameters(message))
}
}
impl Fail for Error {
fn cause(&self) -> Option<&dyn Fail> {
self.context.cause()
}
fn backtrace(&self) -> Option<&Backtrace> {
self.context.backtrace()
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.context.fmt(f)
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ErrType {
InvalidParse(String),
InvalidFile(String),
InvalidSerde(String),
InvalidCode {
code: i32,
message: String,
},
InvalidRequest(String),
InvalidParameters(String),
}
impl fmt::Display for ErrType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ErrType::InvalidParse(ref unk) => {
write!(f, "ERROR: URL was invalid, error was due to: {}", unk)
}
ErrType::InvalidFile(ref unk) => {
write!(f, "ERROR: File path was invalid, error was due to: {}", unk)
}
ErrType::InvalidSerde(ref unk) => {
write!(f, "ERROR: Could not properly serde results: {}", unk)
}
ErrType::InvalidCode { code, message } => write!(
f,
"ERROR: Recieved an invalid status code {} after API call with message: \"{}\"",
code, message
),
ErrType::InvalidRequest(ref unk) => write!(
f,
"ERROR: Failed to make the request, error was due to: {}",
unk
),
ErrType::InvalidParameters(message) => write!(
f,
"ERROR: An invalid parameter was passed, error was due to: {}",
message
),
}
}
}
impl From<ErrType> for Error {
fn from(err_type: ErrType) -> Error {
Error::from(Context::new(err_type))
}
}
impl From<Context<ErrType>> for Error {
fn from(context: Context<ErrType>) -> Error {
Error { context }
}
}
impl From<serde_json::Error> for Error {
fn from(err: serde_json::Error) -> Self {
Error::invalid_serde(err.to_string())
}
}
impl From<url::ParseError> for Error {
fn from(err: url::ParseError) -> Self {
Error::invalid_parse(err.to_string())
}
}
impl From<std::num::ParseIntError> for Error {
fn from(err: std::num::ParseIntError) -> Self {
Error::invalid_parse(err.to_string())
}
}
impl From<std::num::ParseFloatError> for Error {
fn from(err: std::num::ParseFloatError) -> Self {
Error::invalid_parse(err.to_string())
}
}
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Self {
Error::invalid_path(err.to_string())
}
}
impl From<surf::Error> for Error {
fn from(err: surf::Error) -> Self {
Error::invalid_request(err.to_string())
}
}