use crate::{
EntityType, LinksAPIResult, OdesliError, Platform, API_VERSION, BASE_URL, LINKS_ENDPOINT,
};
pub struct ClientBuilder {
api_key: Option<String>,
api_version: String,
http_client: reqwest::Client,
}
impl ClientBuilder {
pub fn with_api_key(mut self, key: String) -> Self {
self.api_key = Some(key);
self
}
pub fn with_api_version(mut self, version: String) -> Self {
self.api_version = version;
self
}
pub fn with_http_client(mut self, client: reqwest::Client) -> Self {
self.http_client = client;
self
}
pub fn build(self) -> OdesliClient {
OdesliClient {
api_key: self.api_key,
api_url: format!("{}/{}", BASE_URL, self.api_version),
http_client: self.http_client,
}
}
}
impl Default for ClientBuilder {
fn default() -> Self {
Self {
api_key: None,
api_version: String::from(API_VERSION),
http_client: reqwest::Client::default(),
}
}
}
#[derive(Clone)]
pub struct OdesliClient {
api_key: Option<String>,
api_url: String,
http_client: reqwest::Client,
}
impl OdesliClient {
async fn get(&self, mut params: Vec<(&str, &str)>) -> Result<LinksAPIResult, OdesliError> {
if let Some(key) = self.api_key.as_ref() {
params.push(("key", key.as_str()));
}
let api_endpoint = format!("{}/{}", self.api_url, LINKS_ENDPOINT);
match self
.http_client
.get(api_endpoint)
.query(params.as_slice())
.send()
.await
{
Ok(res) => {
let status_code = res.status();
let body = res.text().await.unwrap();
if status_code.as_u16() != 200 {
return Err(OdesliError::Non200StatusCode { status_code, body });
}
serde_json::from_str::<LinksAPIResult>(&body).map_err(|err| {
OdesliError::ParseError {
error: err.to_string(),
body,
}
})
}
Err(err) => Err(OdesliError::ReqwestError(err)),
}
}
pub async fn get_by_url(&self, url: &str) -> Result<LinksAPIResult, OdesliError> {
self.get(vec![("url", url)]).await
}
pub async fn get_by_id(
&self,
id: &str,
platform: &Platform,
entity_type: &EntityType,
) -> Result<LinksAPIResult, OdesliError> {
self.get(vec![
("id", id),
("platform", platform.as_str()),
("type", entity_type.as_str()),
])
.await
}
}