use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use serde_json;
use crate::error::Error;
pub struct Client {
client: reqwest::Client,
host: String,
api_key: String,
}
#[derive(Debug, Deserialize)]
pub struct Data<T> {
pub data: T,
}
impl Client {
pub fn new(apikey: impl Into<String>) -> Client {
Client::from_url("https://api.opennode.co", apikey)
}
pub fn from_url(host: impl Into<String>, apikey: impl Into<String>) -> Client {
Client {
client: reqwest::Client::new(),
api_key: apikey.into(),
host: host.into(),
}
}
pub fn with_api_key(self, apikey: impl Into<String>) -> Client {
let mut clt = self;
clt.api_key = apikey.into();
clt
}
pub fn with_host(self, host: impl Into<String>) -> Client {
let mut clt = self;
clt.host = host.into();
clt
}
pub async fn get<S, T>(&self, path: &str, params: Option<S>) -> Result<T, Error>
where
S: Into<String>,
T: DeserializeOwned,
{
let p = params.map_or("".to_string(), |par| (par.into()));
let url = self.host.to_owned() + path + &p;
let res = self.client.get(&url)
.header("Authorization", self.api_key.clone())
.send()
.await
.map_err(|e| Error::Http(e))?;
if res.status().is_success() {
let d: Data<T> = res.json().await.map_err(|e| Error::Http(e))?;
return Ok(d.data);
}
let e: opennode::error::RequestError = res.json().await.map_err(|e|{Error::Http(e)})?;
Err(Error::Opennode(e))
}
pub async fn post<P, T>(&self, path: &str, payload: Option<P>) -> Result<T, Error>
where
P: Serialize,
T: DeserializeOwned,
{
let mut body: Vec<u8> = Vec::new();
let mut content_type = "".to_string();
if let Some(p) = payload {
body = serde_json::to_vec(&p).unwrap();
content_type = "application/json".to_string();
}
let url = self.host.to_owned() + path;
let res = self.client.post(&url)
.header("Content-Type", content_type)
.header("Authorization", self.api_key.clone())
.body(body)
.send()
.await
.map_err(|e| Error::Http(e))?;
if res.status().is_success() {
let d: Data<T> = res.json().await.map_err(|e| Error::Http(e))?;
return Ok(d.data);
}
let e: opennode::error::RequestError = res.json().await.map_err(|e|{Error::Http(e)})?;
Err(Error::Opennode(e))
}
}