brasilapi_client/
errors.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Serialize, Deserialize, Debug)]
4pub struct CepDetailedError {
5    name: String,
6    message: String,
7    service: String,
8
9}
10
11// impl CepDetailedError {
12//     fn new(name: &str, message: &str, service: &str) -> CepDetailedError {
13//         CepDetailedError {
14//             message: message.into(), 
15//             name: name.into(),
16//             service: service.into()
17//         }
18//     }
19// }
20
21/// An enum representing the errors that can occur.
22#[derive(Debug)]
23#[non_exhaustive]
24pub enum Error {
25    BrasilApiError {
26        message: String,
27        name: String,
28        r#type: String,
29    },
30    BrasilCepApiError {
31        message: String,
32        name: String,
33        r#type: String,
34        errors: Vec<CepDetailedError>
35    },
36    NotExpectedRequestError,
37    HttpError(isahc::Error),
38    SerdeJsonError(serde_json::Error),
39    InvalidInputLenError {
40        name: String,
41        min: i32,
42        max: i32
43    },
44    InvalidInputRangeError {
45        name: String,
46        min: i32,
47        max: i32
48    }
49}
50
51impl std::fmt::Display for CepDetailedError {
52    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53        write!(
54            f,
55            "Name: {}
56            Message: {}
57            Service:{}",
58            self.name, self.message, self.service
59        )
60    }
61}
62
63impl std::fmt::Display for Error {
64    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
65        match self {
66            Error::BrasilApiError {
67                message,
68                name,
69                r#type
70            } => write!(
71                fmt,
72                "Error during BrasilApiCall [
73                    message: {}
74                    name: {}
75                    type: {}]",
76                message,
77                name,
78                r#type,
79            ),
80            Error::BrasilCepApiError {
81                message,
82                name,
83                r#type,
84                errors
85            } => write!(
86                fmt,
87                "Error during BrasilApiCall [CEP] [
88                    message: {}
89                    name: {}
90                    type: {}
91                    errors: {:#?}]",
92                message,
93                name,
94                r#type,
95                errors
96            ),
97            Error::HttpError(e) => write!(fmt, "HTTP request failed: {}", e),
98            Error::NotExpectedRequestError => write!(fmt, "Not Expected Error"),
99            Error::SerdeJsonError(_) => todo!(),
100            Error::InvalidInputLenError { name, min, max } => write!(fmt,
101            "Field [{}] expected length should be between {} and {}",
102            name, 
103            min, 
104            max),
105            Error::InvalidInputRangeError { name, min, max } => write!(fmt,
106                "Field [{}] value range should be between {} and {}",
107                name, 
108                min, 
109                max),
110        }
111    }
112}
113
114impl std::error::Error for Error {}
115
116impl From<&serde_json::Value> for Error {
117    fn from(json: &serde_json::Value) -> Error {
118
119        let message = json
120            .get("message")
121            .and_then(|v| v.as_str())
122            .map(|s| s.to_string())
123            .unwrap_or_else(|| json.to_string());
124
125        let name = json
126            .get("name")
127            .and_then(|v| v.as_str())
128            .map(|s| s.to_string())
129            .unwrap_or_else(String::new);
130
131        let ztype = json
132        .get("type")
133        .and_then(|v| v.as_str())
134        .map(|s| s.to_string())
135        .unwrap_or_else(String::new);
136
137        if !json["errors"].is_array() {
138            return Error::BrasilApiError {
139                message,
140                name,
141                r#type: ztype,
142            };
143        }
144
145        let errors = Vec::<CepDetailedError>::deserialize(&json["errors"]).unwrap();
146
147        Error::BrasilCepApiError {
148            message,
149            name,
150            r#type: ztype,
151            errors
152        }
153    }
154}
155
156impl From<isahc::Error> for Error {
157    fn from(error: isahc::Error) -> Error {
158        if error.kind() == isahc::error::ErrorKind::ConnectionFailed {
159            Error::NotExpectedRequestError
160        } else {
161            Error::HttpError(error)
162        }
163    }
164}