use serde::Deserialize;
pub(crate) type HttpResult = Result<reqwest::Response, reqwest::Error>;
#[derive(Debug, Clone, Deserialize, Eq, PartialEq)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum ErrorCode {
Valid,
NotFound,
Forbidden,
BadRequest,
RateLimited,
Unauthorized,
UsageExceeded,
InternalServerError,
InvalidKeyType,
NotUnique,
Conflict,
DeleteProtected,
Expired,
Disabled,
TooManyRequests,
#[serde(other)]
Unknown,
}
#[allow(clippy::module_name_repetitions)]
#[derive(Debug, Clone, Deserialize, Eq, PartialEq)]
pub struct HttpError {
pub code: ErrorCode,
pub message: String,
}
impl HttpError {
#[must_use]
pub(crate) fn new(code: ErrorCode, message: String) -> Self {
Self { code, message }
}
}
#[derive(Deserialize, Debug, Clone, Eq, PartialEq)]
#[must_use = "this `Wrapped` result may be an `Err` variant, which should be handled"]
pub(crate) enum Wrapped<T> {
#[serde(rename = "error")]
Err(HttpError),
#[serde(untagged)]
Ok(T),
}
impl<T> From<Wrapped<T>> for Result<T, HttpError> {
fn from(wrapped: Wrapped<T>) -> Self {
match wrapped {
Wrapped::Err(err) => Err(err),
Wrapped::Ok(res) => Ok(res),
}
}
}
#[cfg(test)]
mod tests {
use super::ErrorCode;
use super::HttpError;
use super::Wrapped;
#[test]
fn test_from_wrapped_ok() {
let wrapped = Wrapped::Ok(120);
let result: Result<_, HttpError> = wrapped.into();
assert_eq!(result.unwrap(), 120);
}
#[test]
fn test_from_wrapped_err() {
let err = HttpError::new(ErrorCode::Conflict, "test".to_string());
let wrapped = Wrapped::Err(err.clone());
let result: Result<u8, HttpError> = wrapped.into();
assert_eq!(result.unwrap_err(), err);
}
}