1use std::fmt;
8
9pub type Result<T> = std::result::Result<T, Error>;
11
12#[derive(Debug)]
13pub(crate) enum Kind {
14 Reqwest,
15 UrlParse
16}
17
18pub struct Error {
19 kind: Kind,
20 message: String,
21 status: Option<reqwest::StatusCode>
22}
23
24impl Error {
25 pub fn is_reqwest(&self) -> bool {
27 matches!(self.kind, Kind::Reqwest)
28 }
29
30 pub fn is_url_parse(&self) -> bool {
32 matches!(self.kind, Kind::UrlParse)
33 }
34
35 pub fn message(&self) -> String {
37 self.message.clone()
38 }
39
40 pub fn status(&self) -> Option<u16> {
42 self.status.map(|e| e.as_u16())
43 }
44
45 pub fn status_code(&self) -> Option<reqwest::StatusCode> {
47 self.status
48 }
49}
50
51impl fmt::Display for Error {
52 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53 match self.kind {
54 Kind::Reqwest => f.write_str("reqwest error")?,
55 Kind::UrlParse => f.write_str("URL parse error")?,
56 };
57 write!(f, ", {}", self.message)
58 }
59}
60
61impl fmt::Debug for Error {
62 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63 write!(
64 f,
65 "Error {{ kind: {:?}, message: {}, status: {:?} }}",
66 self.kind, self.message, self.status
67 )
68 }
69}
70
71impl From<reqwest::Error> for Error {
73 fn from(error: reqwest::Error) -> Self {
74 Error {
75 kind: Kind::Reqwest,
76 message: error.to_string(),
77 status: error.status()
78 }
79 }
80}
81
82impl From<url::ParseError> for Error {
84 fn from(error: url::ParseError) -> Self {
85 Error {
86 kind: Kind::UrlParse,
87 message: error.to_string(),
88 status: None
89 }
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn error() {
99 let error = Error {
101 kind: Kind::Reqwest,
102 message: "a reqwest error".to_string(),
103 status: Some(reqwest::StatusCode::from_u16(500).unwrap())
104 };
105 assert_eq!("Error { kind: Reqwest, message: a reqwest error, status: Some(500) }", format!("{error:?}"));
106 assert_eq!("reqwest error, a reqwest error", error.to_string());
107 assert_eq!("a reqwest error", error.message());
108 assert_eq!(Some(500), error.status());
109 assert_eq!(Some(reqwest::StatusCode::INTERNAL_SERVER_ERROR), error.status_code());
110 assert!(error.is_reqwest());
111 let error = Error {
113 kind: Kind::UrlParse,
114 message: "an URL parse error".to_string(),
115 status: None
116 };
117 assert_eq!("Error { kind: UrlParse, message: an URL parse error, status: None }", format!("{error:?}"));
118 assert_eq!("URL parse error, an URL parse error", error.to_string());
119 assert_eq!("an URL parse error", error.message());
120 assert_eq!(None, error.status());
121 assert!(error.is_url_parse());
122 }
123}