use reqwest::Client;
use serde::Deserialize;
use crate::ApiHttpResponse;
use crate::schema::*;
static USER_AGENT: &str = concat!(
env!("CARGO_PKG_NAME"),
"/",
env!("CARGO_PKG_VERSION"),
);
pub struct ExploreApiEndPoint {
pub url: String,
client: Client,
}
impl ExploreApiEndPoint {
pub fn new (url: &str) -> Self {
Self {
url: url.to_string(),
client: Client::builder()
.user_agent(USER_AGENT)
.build()
.expect("A HTTP client should be built"),
}
}
pub async fn get_datasets(&self) -> DatasetsCollection {
let url = self.get_url("/catalog/datasets");
self.fetch(url).await
}
pub async fn export_datasets_catalog(&self, format: &str) -> ApiHttpResponse {
let url = self
.get_url("/catalog/exports/?")
.replace("?", format);
self.fetch_resource(url).await
}
pub async fn get_facets(&self) -> FacetsCollection {
let url = self.get_url("/catalog/facets");
self.fetch(url).await
}
pub async fn get_dataset_records(&self, dataset_id: &str) -> Results {
let url = self
.get_url("/catalog/datasets/?/records")
.replace("?", dataset_id);
self.fetch(url).await
}
pub async fn export_dataset(&self, dataset_id: &str, format: &str) -> ApiHttpResponse {
let url = self
.get_url("/catalog/datasets/:id/exports/:format")
.replace(":id", dataset_id)
.replace(":format", format);
self.fetch_resource(url).await
}
pub async fn get_dataset_information(&self, dataset_id: &str) -> Dataset {
let mut url = self.get_url("/catalog/datasets/");
url.push_str(dataset_id);
self.fetch(url).await
}
pub async fn get_dataset_facets(&self, dataset_id: &str) -> FacetsCollection {
let url = self
.get_url("/catalog/datasets/?/facets")
.replace("?", dataset_id);
self.fetch(url).await
}
pub async fn get_dataset_attachments(&self, dataset_id: &str) -> AttachmentCollection {
let url = self
.get_url("/catalog/datasets/?/attachments")
.replace("?", dataset_id);
self.fetch(url).await
}
pub async fn get_dataset_record(&self, dataset_id: &str, record_id: &str) -> Record {
let url = self
.get_url("/catalog/datasets/:id/records/:record")
.replace(":id", dataset_id)
.replace(":record", record_id);
self.fetch(url).await
}
fn get_url (&self, method: &str) -> String {
format!("{}{}", self.url, method)
}
async fn fetch_resource (&self, url: String) -> ApiHttpResponse {
self.client.get(url)
.send().await
.expect("Can't fetch API URL")
}
async fn fetch<T> (&self, url: String) -> T where for<'a> T: Deserialize<'a> {
let body = self.fetch_resource(url).await
.text().await
.expect("Can't get HTTP response content");
serde_json::from_str(&body)
.expect("HTTP response should be a valid dataset, can't parse it.")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_url () {
let endpoint = ExploreApiEndPoint::new("https://foo");
assert_eq!("https://foo/bar", endpoint.get_url("/bar"));
assert_eq!("https://foo", endpoint.get_url(""));
}
}