use thiserror::Error;
use std::net::AddrParseError;
use std::collections::HashMap;
#[derive(Error, Debug, Clone)]
pub enum ApiErrorCode {
#[error("Authentication error (103)")]
AuthError103,
#[error("Server error (500)")]
ServerError500,
#[error("Too many requests (429)")]
TooManyRequests429,
#[error("Not found (404)")]
NotFound404,
#[error("Forbidden (403)")]
Forbidden403,
#[error("Bad request (400)")]
BadRequest400,
#[error("Service unavailable (503)")]
ServiceUnavailable503,
#[error("Unknown error code: {0}")]
Unknown(String),
}
impl From<&str> for ApiErrorCode {
fn from(code: &str) -> Self {
match code {
"103" => ApiErrorCode::AuthError103,
"500" => ApiErrorCode::ServerError500,
"429" => ApiErrorCode::TooManyRequests429,
"404" => ApiErrorCode::NotFound404,
"403" => ApiErrorCode::Forbidden403,
"400" => ApiErrorCode::BadRequest400,
"503" => ApiErrorCode::ServiceUnavailable503,
_ => ApiErrorCode::Unknown(code.to_string()),
}
}
}
#[derive(Debug, Clone)]
pub struct ApiErrorDetails {
pub code: ApiErrorCode,
pub message: String,
pub headers: Option<HashMap<String, String>>,
pub body: Option<String>,
}
#[derive(Error, Debug)]
pub enum PixivError {
#[error("Network error: {0}")]
NetworkError(#[from] NetworkError),
#[error("Authentication error: {0}")]
AuthError(String),
#[error("API error: {0}")]
ApiError(String),
#[error("API error: {details:?}")]
ApiErrorWithDetails {
details: ApiErrorDetails,
},
#[error("JSON parsing error: {0}")]
JsonError(#[from] serde_json::Error),
#[error("Illustration not found: {0}")]
IllustNotFound(u64),
#[error("Illustration access restricted: {0}")]
IllustRestricted(u64),
#[error("Search parameter error: {0}")]
SearchParameterError(String),
#[error("Ranking parameter error: {0}")]
RankingParameterError(String),
#[error("Recommended parameter error: {0}")]
RecommendedParameterError(String),
#[error("Unknown error: {0}")]
Unknown(String),
#[error("Public API error: {0}")]
PublicApiError(String),
#[error("SNI bypass error: {0}")]
SniBypassError(#[from] SniBypassError),
}
#[derive(Error, Debug)]
pub enum NetworkError {
#[error("HTTP request error: {0}")]
RequestError(#[from] reqwest::Error),
#[error("Connection timeout")]
Timeout,
#[error("Invalid URL: {0}")]
InvalidUrl(String),
}
#[derive(Error, Debug)]
pub enum SniBypassError {
#[error("Invalid IP address: {0}")]
InvalidIp(String),
#[error("Connection error: {0}")]
ConnectionError(#[from] reqwest::Error),
#[error("IP parsing error: {0}")]
IpParseError(#[from] AddrParseError),
}
impl From<reqwest::Error> for PixivError {
fn from(err: reqwest::Error) -> Self {
PixivError::NetworkError(NetworkError::RequestError(err))
}
}
pub type Result<T> = std::result::Result<T, PixivError>;