tcgdex_api/
errors.rs

1//! Allow to get error information.
2
3use crate::is_empty::IsEmpty;
4use crate::query::Response;
5use serde::Deserialize;
6use thiserror::Error;
7
8/// A `Result` alias where the `Err` case is [`Error`].
9pub type Result<T> = std::result::Result<T, ApiError>;
10
11/// Error returned by TCGDEX API in some cases of bad request.
12#[derive(Deserialize, Debug, PartialEq, Eq)]
13pub struct TcgdexError {
14    /// A URL that identifies the problem type.
15    #[serde(rename = "type")]
16    pub _type: String,
17
18    /// Summary of the problem.
19    pub title: String,
20
21    /// The HTTP status code.
22    pub status: u16,
23
24    /// Query that cause the problem.
25    pub endpoint: String,
26
27    /// Method used for query
28    pub method: String,
29
30    /// Lang used.
31    #[serde(default)]
32    pub lang: String,
33
34    /// Details about the problem.
35    #[serde(default)]
36    pub details: String,
37}
38
39/// The errors that may occur.
40#[derive(Debug, Error)]
41pub enum ApiError {
42    /// Error from reqwest
43    #[error("Reqwest error : {}", .0)]
44    Reqwest(#[from] reqwest::Error),
45
46    /// Error from TCGDEX API.
47    #[error("Tcgdex error : {}", .0.title)]
48    TcgdexApi(TcgdexError),
49
50    /// Response is empty.
51    #[error("Response is empty")]
52    EmptyResponse,
53}
54
55impl ApiError {
56    /// Returns true if the error is from reqwest
57    #[must_use]
58    pub fn is_reqwest(&self) -> bool {
59        matches!(self, Self::Reqwest(_))
60    }
61
62    /// Returns true if the error is from the TCGDEX API.
63    #[must_use]
64    pub fn is_tcgdexapi(&self) -> bool {
65        matches!(self, Self::TcgdexApi(_))
66    }
67
68    /// Returns true if the error is from an empty response.
69    #[must_use]
70    pub fn is_empty_response(&self) -> bool {
71        matches!(self, Self::EmptyResponse)
72    }
73
74    /// Returns the TCGDEX error message or None if error is not from TCGDEX.
75    #[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
84// NOTE: reqwest error cannot be compared.
85impl 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}