use models::response::{DiscoveryPagedData, DiscoveryPagedResponse, DiscoveryResponse};
use reqwest::Client;
use serde::de::DeserializeOwned;
pub mod error;
mod event;
pub mod models;
pub(crate) mod request_builder;
pub struct Discovery {
api_key: String,
client: Client,
}
impl Discovery {
const URL: &'static str = "https://app.ticketmaster.com/discovery/v2";
pub(crate) async fn call_paged_request<R: DeserializeOwned>(
&self,
endpoint: &str,
args: String,
) -> error::Result<DiscoveryPagedData<R>> {
let args = if args.is_empty() {
String::new()
} else {
format!("&{args}")
};
let raw_response = self
.client
.get(format!(
"{}{endpoint}?apikey={}{args}",
Self::URL,
self.api_key
))
.send()
.await?
.text()
.await?;
if let Ok(data) = serde_json::from_str::<DiscoveryPagedResponse<R>>(&raw_response) {
data.into_result()
} else {
tracing::info!("{raw_response}");
let data: DiscoveryPagedData<R> = serde_json::from_str(&raw_response)?;
Ok(data)
}
}
pub(crate) async fn call_request<R: DeserializeOwned>(
&self,
endpoint: &str,
args: String,
) -> error::Result<R> {
let args = if args.is_empty() {
String::new()
} else {
format!("&{args}")
};
let raw_response = self
.client
.get(format!(
"{}{endpoint}?apikey={}{args}",
Self::URL,
self.api_key
))
.send()
.await?
.text()
.await?;
if let Ok(data) = serde_json::from_str::<DiscoveryResponse<R>>(&raw_response) {
data.into_result()
} else {
tracing::info!("{raw_response}");
let data: R = serde_json::from_str(&raw_response)?;
Ok(data)
}
}
pub fn from_env(env_key: &str) -> Result<Self, std::env::VarError> {
Ok(Self::new(std::env::var(env_key)?))
}
pub fn new(api_key: impl ToString) -> Self {
Self {
api_key: api_key.to_string(),
client: Default::default(),
}
}
pub fn with_client(mut self, client: Client) -> Self {
self.client = client;
self
}
}