libtad_rs/
error.rs

1use crate::http::HTTPError;
2use hmac::crypto_mac::InvalidKeyLength;
3use serde::Deserialize;
4
5#[derive(Debug)]
6/// Internal library errors.
7pub enum Error {
8    /// Error returned from the HTTP client.
9    Http(HTTPError),
10
11    /// Error when generating signature.
12    Signature(InvalidKeyLength),
13}
14
15impl std::fmt::Display for Error {
16    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
17        match self {
18            Self::Http(e) => write!(f, "HTTP Error: {}", e),
19            Self::Signature(e) => write!(f, "Signature Error: {}", e),
20        }
21    }
22}
23
24impl std::error::Error for Error {
25    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
26        match self {
27            Self::Http(e) => Some(e),
28            _ => None,
29        }
30    }
31}
32
33impl From<HTTPError> for Error {
34    fn from(e: HTTPError) -> Self {
35        Self::Http(e)
36    }
37}
38
39impl From<InvalidKeyLength> for Error {
40    fn from(e: InvalidKeyLength) -> Self {
41        Self::Signature(e)
42    }
43}
44
45#[derive(Debug, Deserialize)]
46/// Error returned from the API.
47pub struct ApiError {
48    /// List of API errors.
49    #[serde(deserialize_with = "custom_deserialize::string_or_vec")]
50    pub errors: Vec<String>,
51}
52
53impl std::fmt::Display for ApiError {
54    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
55        write!(f, "API Error: {}", self.errors.join(", "))
56    }
57}
58
59impl std::error::Error for ApiError {}
60
61mod custom_deserialize {
62    use serde::de::{self, value, Deserialize, Deserializer, SeqAccess, Visitor};
63
64    pub fn string_or_vec<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
65    where
66        D: Deserializer<'de>,
67    {
68        struct StringOrVec;
69
70        impl<'de> Visitor<'de> for StringOrVec {
71            type Value = Vec<String>;
72
73            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
74                formatter.write_str("string or list of strings")
75            }
76
77            fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
78            where
79                E: de::Error,
80            {
81                Ok(vec![s.to_owned()])
82            }
83
84            fn visit_seq<S>(self, seq: S) -> Result<Self::Value, S::Error>
85            where
86                S: SeqAccess<'de>,
87            {
88                Deserialize::deserialize(value::SeqAccessDeserializer::new(seq))
89            }
90        }
91
92        deserializer.deserialize_any(StringOrVec)
93    }
94}