1use serde_json::Value;
4use std::fmt;
5
6#[derive(Debug, Clone)]
8pub enum DataForSeoError {
9 Api(DataForSeoApiError),
12 Http(DataForSeoHttpError),
14 System(DataForSeoSystemError),
16}
17
18impl DataForSeoError {
19 pub fn http_status(&self) -> u16 {
21 match self {
22 DataForSeoError::Api(e) => e.http_status,
23 DataForSeoError::Http(e) => e.http_status,
24 DataForSeoError::System(_) => 0,
25 }
26 }
27
28 pub fn api_status_code(&self) -> Option<i32> {
31 match self {
32 DataForSeoError::Api(e) => Some(e.status_code),
33 _ => None,
34 }
35 }
36}
37
38impl fmt::Display for DataForSeoError {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 match self {
41 DataForSeoError::Api(e) => write!(
42 f,
43 "DataForSEO API error (http {}): {} {}",
44 e.http_status, e.status_code, e.status_message
45 ),
46 DataForSeoError::Http(e) => write!(f, "HTTP error {}", e.http_status),
47 DataForSeoError::System(e) => write!(f, "client error: {}", e.message),
48 }
49 }
50}
51
52impl std::error::Error for DataForSeoError {}
53
54impl From<DataForSeoApiError> for DataForSeoError {
55 fn from(value: DataForSeoApiError) -> Self {
56 DataForSeoError::Api(value)
57 }
58}
59
60impl From<DataForSeoHttpError> for DataForSeoError {
61 fn from(value: DataForSeoHttpError) -> Self {
62 DataForSeoError::Http(value)
63 }
64}
65
66impl From<DataForSeoSystemError> for DataForSeoError {
67 fn from(value: DataForSeoSystemError) -> Self {
68 DataForSeoError::System(value)
69 }
70}
71
72#[derive(Debug, Clone)]
78pub struct DataForSeoApiError {
79 pub http_status: u16,
81 pub status_code: i32,
84 pub status_message: String,
86 pub response_body: String,
88}
89
90impl DataForSeoApiError {
91 pub(crate) fn from_envelope(http_status: u16, value: &Value, body: String) -> Self {
92 DataForSeoApiError {
93 http_status,
94 status_code: value
95 .get("status_code")
96 .and_then(Value::as_i64)
97 .unwrap_or_default() as i32,
98 status_message: value
99 .get("status_message")
100 .and_then(Value::as_str)
101 .unwrap_or_default()
102 .to_string(),
103 response_body: body,
104 }
105 }
106}
107
108#[derive(Debug, Clone)]
110pub struct DataForSeoHttpError {
111 pub http_status: u16,
113 pub response_body: String,
115}
116
117impl DataForSeoHttpError {
118 pub fn new(http_status: u16, response_body: String) -> DataForSeoHttpError {
120 DataForSeoHttpError {
121 http_status,
122 response_body,
123 }
124 }
125}
126
127#[derive(Debug, Clone)]
129pub struct DataForSeoSystemError {
130 pub message: String,
132}
133
134impl DataForSeoSystemError {
135 pub fn new<T: Into<String>>(message: T) -> DataForSeoSystemError {
137 DataForSeoSystemError {
138 message: message.into(),
139 }
140 }
141}