use std::fmt::Formatter;
use reqwest::Response;
use serde::{Deserialize, Serialize};
use thiserror::Error;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Error, Debug)]
pub enum Error {
#[error("failure making the request")]
Request(#[from] reqwest::Error),
#[error("daily request returned an error: {0}")]
APIError(DailyCoErrorInfo),
#[error("API key problem: {0}")]
BadAPIKey(&'static str),
#[error("Response requires pagination, which is not implemented yet.")]
RequiresPagination,
}
impl Error {
pub(crate) async fn from_failed_daily_request(response: Response) -> Self {
match response.json().await {
Ok(error) => Self::APIError(error),
Err(err) => Self::Request(err),
}
}
}
#[derive(Debug, Copy, Clone, Deserialize, Serialize, Eq, PartialEq)]
#[serde(rename_all = "kebab-case")]
pub enum DailyCoErrorKind {
AuthenticationError,
AuthorizationHeaderError,
JsonParsingError,
InvalidRequestError,
RateLimitError,
ServerError,
NotFound,
}
impl std::fmt::Display for DailyCoErrorKind {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let disp = match self {
Self::AuthenticationError => "authentication-error",
Self::AuthorizationHeaderError => "authorization-header-error",
Self::JsonParsingError => "json-parsing-error",
Self::InvalidRequestError => "invalid-request-error",
Self::RateLimitError => "rate-limit-error",
Self::ServerError => "server-error",
Self::NotFound => "not-found",
};
f.write_str(disp)
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct DailyCoErrorInfo {
pub error: Option<DailyCoErrorKind>,
pub info: Option<String>,
}
impl std::fmt::Display for DailyCoErrorInfo {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
if let Some(error_kind) = self.error {
write!(f, "Error: {}", error_kind)?;
}
if let Some(info) = &self.info {
write!(f, "Info: {}", info)
} else {
f.write_str("Info: Unspecified")
}
}
}