1use crate::is_empty::IsEmpty;
4use crate::query::Response;
5use serde::Deserialize;
6use thiserror::Error;
7
8pub type Result<T> = std::result::Result<T, ApiError>;
10
11#[derive(Deserialize, Debug, PartialEq, Eq)]
13pub struct TcgdexError {
14 #[serde(rename = "type")]
16 pub _type: String,
17
18 pub title: String,
20
21 pub status: u16,
23
24 pub endpoint: String,
26
27 pub method: String,
29
30 #[serde(default)]
32 pub lang: String,
33
34 #[serde(default)]
36 pub details: String,
37}
38
39#[derive(Debug, Error)]
41pub enum ApiError {
42 #[error("Reqwest error : {}", .0)]
44 Reqwest(#[from] reqwest::Error),
45
46 #[error("Tcgdex error : {}", .0.title)]
48 TcgdexApi(TcgdexError),
49
50 #[error("Response is empty")]
52 EmptyResponse,
53}
54
55impl ApiError {
56 #[must_use]
58 pub fn is_reqwest(&self) -> bool {
59 matches!(self, Self::Reqwest(_))
60 }
61
62 #[must_use]
64 pub fn is_tcgdexapi(&self) -> bool {
65 matches!(self, Self::TcgdexApi(_))
66 }
67
68 #[must_use]
70 pub fn is_empty_response(&self) -> bool {
71 matches!(self, Self::EmptyResponse)
72 }
73
74 #[must_use]
76 pub fn get_tcgdex_error(self) -> Option<TcgdexError> {
77 match self {
78 Self::TcgdexApi(err) => Some(err),
79 _ => None,
80 }
81 }
82}
83
84impl PartialEq for ApiError {
86 fn eq(&self, other: &Self) -> bool {
87 match (self, other) {
88 (Self::TcgdexApi(a), Self::TcgdexApi(b)) => a == b,
89 (Self::EmptyResponse, Self::EmptyResponse) => true,
90 _ => false,
91 }
92 }
93}
94
95pub(crate) fn set_error<T>(response: Response<T>) -> Result<T>
96where
97 T: IsEmpty,
98{
99 match response {
100 Response::Data(obj) => {
101 if obj.is_empty() {
102 Err(ApiError::EmptyResponse)
103 } else {
104 Ok(obj)
105 }
106 }
107 Response::Error(error) => Err(ApiError::TcgdexApi(error)),
108 }
109}