use crate::pagination::Object;
use serde::{Deserialize, Serialize};
use std::fmt::{Display, Formatter};
use std::num::NonZeroU16;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Invalid NVD API Token: {}", source)]
InvalidApiToken {
source: reqwest::header::InvalidHeaderValue,
},
#[error("Unable to build reqwest HTTP client: {}", source)]
BuildingClient { source: reqwest::Error },
#[error("Error sending HTTP request: {}", source)]
RequestFailed {
#[from]
source: reqwest::Error,
},
#[error("Error reading response: {}", source)]
ResponseIo { source: reqwest::Error },
#[error("Error parsing json response: {}", source)]
JsonParse { source: serde_json::Error },
#[error("Unexpected API Response")]
UnexpectedResponse { response: Object },
#[error("API Error {}({}): {}", .error.code, .error.status, .error.message)]
Api { error: ErrorResponse },
}
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[serde(transparent)]
pub struct StatusCode(NonZeroU16);
impl Display for StatusCode {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Clone)]
pub struct ErrorResponse {
pub status: StatusCode,
pub code: ErrorCode,
pub message: String,
}
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Clone)]
#[serde(rename_all = "snake_case")]
pub enum ErrorCode {
InvalidJson,
InvalidRequestUrl,
InvalidRequest,
MissionVersion,
Unauthorized,
RestrictedResource,
ObjectNotFound,
ConflictError,
RateLimited,
InternalServerError,
ServiceUnavailable,
#[serde(other)] Unknown,
}
impl Display for ErrorCode {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{self:?}")
}
}