1use reqwest::StatusCode;
3use serde::{Serialize, Serializer};
4
5pub type Result<T> = std::result::Result<T, Error>;
7
8#[derive(Debug, Clone, thiserror::Error, PartialEq, Eq, Serialize)]
10#[non_exhaustive]
11pub enum Error {
12 #[error("Failed to get valid response from server: {0}")]
13 Response(String),
14
15 #[error("Server responded with {status}: {error}")]
16 ResponseStatus {
17 #[serde(serialize_with = "serialize_status")]
18 status: StatusCode,
19 error: String,
20 },
21
22 #[error("Failed to deserialize the response: {0}")]
23 Deserialization(String),
24
25 #[error("Paginated item failed deserialized: {0}")]
26 PaginationItemDeserialization(String),
27
28 #[error("Time parsing error: {0}")]
31 TimeFormatError(String),
32
33 #[error("Failed to parse item into valid URI: {0}")]
34 InvalidUri(String),
35
36 #[error("Failed to retrieve the HATEOAS URI: {0}")]
37 MissingUri(&'static str),
38
39 #[error("Failed to parse the final segment of the path as an ID.")]
40 InvalidId,
41}
42
43fn serialize_status<S: Serializer>(
44 status: &StatusCode,
45 serializer: S,
46) -> std::result::Result<S::Ok, S::Error> {
47 serializer.serialize_u16(status.as_u16())
48}
49
50impl Error {
51 pub(crate) fn pag_item(s: String) -> Self {
53 Self::PaginationItemDeserialization(s)
54 }
55}
56
57impl From<reqwest::Error> for Error {
58 fn from(value: reqwest::Error) -> Self {
59 let error = value.to_string();
60 match value.status() {
61 Some(status) => Self::ResponseStatus { status, error },
62 None => Error::Response(error),
63 }
64 }
65}
66
67impl From<serde_json::Error> for Error {
68 fn from(value: serde_json::Error) -> Self {
69 Error::Deserialization(value.to_string())
70 }
71}
72
73impl From<time::error::Error> for Error {
74 fn from(value: time::error::Error) -> Self {
75 Error::TimeFormatError(value.to_string())
76 }
77}
78
79impl From<time::error::Format> for Error {
80 fn from(value: time::error::Format) -> Self {
81 Error::TimeFormatError(value.to_string())
82 }
83}
84
85impl From<url::ParseError> for Error {
86 fn from(value: url::ParseError) -> Self {
87 Self::InvalidUri(value.to_string())
88 }
89}