scoopit_api/
error.rs

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}