1use std::fmt::{Debug, Display};
2
3#[derive(Debug)]
4pub struct Error {
5 inner: Inner,
6}
7
8impl Error {
9 pub fn is_not_found(&self) -> bool {
10 if let Inner::NotFound = self.inner {
11 true
12 } else {
13 false
14 }
15 }
16 pub fn is_forbidden(&self) -> bool {
17 if let Inner::Forbidden = self.inner {
18 true
19 } else {
20 false
21 }
22 }
23}
24
25impl std::error::Error for Error {}
26
27impl Display for Error {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 Display::fmt(&self.inner, f)
30 }
31}
32
33impl From<reqwest::Error> for Error {
34 fn from(e: reqwest::Error) -> Self {
35 match e.status() {
36 Some(status) if status.as_u16() == 404 => Inner::NotFound.into(),
37 Some(status) if status.as_u16() == 403 => Inner::Forbidden.into(),
38 _ => Inner::from(e).into(),
39 }
40 }
41}
42impl From<anyhow::Error> for Error {
43 fn from(e: anyhow::Error) -> Self {
44 Self { inner: e.into() }
45 }
46}
47
48impl From<Inner> for Error {
49 fn from(inner: Inner) -> Self {
50 Self { inner }
51 }
52}
53
54impl From<serde_json::Error> for Error {
55 fn from(e: serde_json::Error) -> Self {
56 Self { inner: e.into() }
57 }
58}
59
60#[derive(thiserror::Error, Debug)]
61pub(crate) enum Inner {
62 #[error("Requested resource not found")]
63 NotFound,
64 #[error("Access to requested resource is forbidden")]
65 Forbidden,
66 #[error("An error occurred: {}", .0)]
67 HttpClient(#[from] reqwest::Error),
68 #[error("Unable to deserialize response: {}", .0)]
69 SerdeError(#[from] serde_json::Error),
70 #[error("An error occurred: {}", .0)]
71 Other(#[from] anyhow::Error),
72}