use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("invalid configuration: {0}")]
Config(String),
#[error("invalid URL: {0}")]
Url(#[from] url::ParseError),
#[error("HTTP transport error: {0}")]
Http(#[from] reqwest::Error),
#[error("failed to (de)serialize JSON: {0}")]
Json(#[from] serde_json::Error),
#[error("API error ({status}): {error:?}")]
Api {
status: u16,
error: Box<ApiError>,
},
#[error("API exception ({status}): {exception:?}")]
Exception {
status: u16,
exception: Box<ApiException>,
},
#[error("HTTP {status}: {body}")]
Unexpected {
status: u16,
body: String,
},
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ApiError {
pub error_code: Option<String>,
pub description: Option<String>,
pub action: Option<String>,
#[serde(default)]
pub violations: Vec<ApiErrorViolation>,
#[serde(default)]
pub resources: Vec<ApiErrorResource>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ApiErrorViolation {
pub property: Option<String>,
pub violation: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ApiErrorResource {
pub name: Option<String>,
pub url: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ApiException {
pub request_error: Option<ApiRequestError>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ApiRequestError {
pub service_exception: Option<ApiRequestErrorDetails>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ApiRequestErrorDetails {
pub message_id: Option<String>,
pub text: Option<String>,
#[serde(default)]
pub validation_errors: HashMap<String, Vec<String>>,
}