use std::str::FromStr;
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use crate::types;
#[derive(Debug)]
pub struct Series {
pub version: types::version::ApiVersion,
pub headers: reqwest::header::HeaderMap,
pub body: reqwest::Body,
}
#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
pub struct SeriesResponse {
pub errors: Vec<serde_json::value::Value>,
}
impl Default for Series {
fn default() -> Self {
Self {
version: types::version::ApiVersion::V2,
headers: reqwest::header::HeaderMap::new(),
body: reqwest::Body::from(""),
}
}
}
impl TryFrom<types::version::ApiVersion> for Series {
type Error = &'static str;
fn try_from(v: types::version::ApiVersion) -> Result<Self, Self::Error> {
match v {
types::version::ApiVersion::V2 => Ok(Self::default()),
_ => Err("Unsupported API Version"),
}
}
}
impl Series {
pub fn new() -> Self {
tracing::info!(target: "/v2/series", "Series Route Created");
Self::default()
}
pub fn target() -> String {
String::from("v2/series")
}
}
#[async_trait]
impl types::route::Route<SeriesResponse> for Series {
fn path(&self) -> String {
String::from("v2/series")
}
fn route(self, _: std::string::String) -> Self {
self
}
fn with_header(mut self, key: &str, value: &str) -> Self {
self.headers.insert(
reqwest::header::HeaderName::from_str(key).unwrap(),
reqwest::header::HeaderValue::from_str(value).unwrap(),
);
self
}
fn headers(mut self, headers: Vec<(&str, &str)>) -> Self {
for (key, value) in headers {
self.headers.insert(
reqwest::header::HeaderName::from_str(key).unwrap(),
reqwest::header::HeaderValue::from_str(value).unwrap(),
);
}
self
}
fn with_api_key(mut self, key: &str) -> Self {
self.headers.insert(
reqwest::header::HeaderName::from_str("DD-API-KEY").unwrap(),
reqwest::header::HeaderValue::from_str(key).unwrap(),
);
self
}
fn with_application_key(mut self, key: &str) -> Self {
self.headers.insert(
reqwest::header::HeaderName::from_str("DD-APPLICATION-KEY").unwrap(),
reqwest::header::HeaderValue::from_str(key).unwrap(),
);
self
}
fn body<T: Into<reqwest::Body>>(mut self, body: T) -> Self {
self.body = body.into();
self
}
async fn execute(
self,
) -> (
reqwest::StatusCode,
Result<SeriesResponse, Option<reqwest::Error>>,
) {
let url = format!("{}/{}", types::base::BASE_API_URL, self.path());
tracing::info!(target: "/v2/series", "Sending Request to {}", url);
let mut req_builder: reqwest::RequestBuilder = reqwest::Client::new().post(url);
req_builder = req_builder.headers(self.headers.clone());
req_builder = req_builder.body(self.body);
let response = req_builder.send().await;
match response {
Ok(r) => {
let status_code = r.status();
match r.json::<SeriesResponse>().await {
Ok(json_response) => {
tracing::info!(target: "/v2/series", "Deserialized Response into json: {:?}", json_response);
return (status_code, Ok(json_response));
}
Err(e) => {
tracing::error!(target: "/v2/series", "Failed to parse error response {:?}", e);
return (status_code, Err(Some(e)));
}
}
}
Err(e) => {
tracing::error!(target: "/v2/series", "Request failed with error {:?}", e);
return (
e.status().unwrap_or(reqwest::StatusCode::BAD_REQUEST),
Err(Some(e)),
);
}
}
}
}