use serde::Deserialize;
#[derive(Debug)]
pub enum Error {
RequestError(reqwest::Error),
ResponseParseError(reqwest::Error),
InvalidArgument(String),
WitError(ErrorResponse),
URLParseError(url::ParseError),
}
impl From<reqwest::Error> for Error {
fn from(error: reqwest::Error) -> Self {
if error.is_body() || error.is_decode() {
Self::ResponseParseError(error)
} else {
Self::RequestError(error)
}
}
}
impl From<ErrorResponse> for Error {
fn from(error_json: ErrorResponse) -> Self {
Self::WitError(error_json)
}
}
impl From<url::ParseError> for Error {
fn from(error: url::ParseError) -> Self {
Self::URLParseError(error)
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::RequestError(source) => write!(f, "request error: {}", source),
Self::ResponseParseError(source) => write!(f, "response parse error: {}", source),
Self::InvalidArgument(details) => write!(f, "invalid argument: {}", details),
Self::WitError(source) => write!(f, "error from wit.ai: {}", source),
Self::URLParseError(source) => write!(f, "URL parse error: {}", source),
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::RequestError(source) => Some(source),
Self::ResponseParseError(source) => Some(source),
Self::InvalidArgument(_) => None,
Self::WitError(source) => Some(source),
Self::URLParseError(source) => Some(source),
}
}
}
#[derive(Debug, Deserialize)]
pub struct ErrorResponse {
pub error: String,
pub code: String,
}
impl std::fmt::Display for ErrorResponse {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}: {}", self.code, self.error)
}
}
impl std::error::Error for ErrorResponse {}