mod client;
mod errors;
mod rate;
pub use client::*;
pub use errors::*;
pub use rate::Rate;
use reqwest::{Response, StatusCode};
use serde::{Deserialize, Serialize};
const CONTENT_TYPE: &str = "application/json; charset=utf-8";
const USER_AGENT: &str = "ddclient-rs/0.1.0";
const DEFAULT_BASE_URL: &str = "https://api.directdecisions.com";
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct VotingResults {
pub tie: bool,
pub results: Vec<VotingResult>,
pub duels: Option<Vec<Duels>>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct Duels {
pub left: ChoiceStrength,
pub right: ChoiceStrength,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct ChoiceStrength {
pub index: isize,
pub choice: String,
pub strength: isize,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct VotingResult {
pub choice: String,
pub index: i32,
pub wins: i32,
pub percentage: f32,
pub strength: usize,
pub advantage: usize,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct Voting {
pub id: String,
pub choices: Vec<String>,
}
#[derive(Debug, Serialize, Deserialize)]
struct ApiErrorResponse {
code: i32,
message: String,
errors: Vec<String>,
}
async fn handle_api_response<T: serde::de::DeserializeOwned>(
response: Response,
) -> Result<T, ApiError> {
match response.status() {
StatusCode::OK => response
.json()
.await
.map_err(|err| ApiError::Client(ClientError::HttpRequestError(err))),
StatusCode::NOT_FOUND => Err(ApiError::NotFound),
StatusCode::UNAUTHORIZED => Err(ApiError::Unauthorized),
StatusCode::FORBIDDEN => Err(ApiError::Forbidden),
StatusCode::TOO_MANY_REQUESTS => Err(ApiError::TooManyRequests),
StatusCode::METHOD_NOT_ALLOWED => Err(ApiError::MethodNotAllowed),
StatusCode::BAD_REQUEST => match response.json::<ApiErrorResponse>().await {
Ok(error_resp) => {
let bad_request_errors = error_resp
.errors
.into_iter()
.filter_map(|err| {
serde_json::from_str::<BadRequestError>(&format!("\"{}\"", err)).ok()
})
.collect();
Err(ApiError::BadRequest(bad_request_errors))
}
Err(_) => Err(ApiError::BadRequest(vec![])),
},
StatusCode::SERVICE_UNAVAILABLE => Err(ApiError::Client(ClientError::ServiceUnavailable)),
StatusCode::BAD_GATEWAY => Err(ApiError::Client(ClientError::BadGateway)),
StatusCode::INTERNAL_SERVER_ERROR => {
let error_message = response.text().await.unwrap_or_default();
Err(ApiError::InternalServerError(error_message))
}
_ => {
let error_message = response.text().await.unwrap_or_default();
Err(ApiError::Other(error_message))
}
}
}