use serde::de::DeserializeOwned;
use crate::MLBError;
#[cfg(not(feature = "_debug"))]
pub async fn get<T: DeserializeOwned>(url: String) -> Result<T> {
let bytes = reqwest::Client::builder().build()?.get(url).send().await?.bytes().await?;
let e = match serde_json::from_slice::<'_, T>(&bytes) {
Ok(t) => return Ok(t),
Err(e) => Error::Serde(e),
};
Err(Error::MLB(serde_json::from_slice::<'_, MLBError>(&bytes).map_err(|_| e)?))
}
#[cfg(feature = "_debug")]
pub async fn get<T: DeserializeOwned>(url: String) -> Result<T> {
let bytes = reqwest::Client::builder().build()?.get(url).send().await?.bytes().await?;
let mut de = serde_json::Deserializer::from_slice(&bytes);
let result: std::result::Result<T, serde_path_to_error::Error<_>> = serde_path_to_error::deserialize(&mut de);
let e = match result {
Ok(t) => return Ok(t),
Err(e) => Error::Serde(e),
};
Err(Error::MLB(serde_json::from_slice::<'_, MLBError>(&bytes).map_err(|_| e)?))
}
pub type Result<T, E = Error> = std::result::Result<T, E>;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error(transparent)]
Network(#[from] ::reqwest::Error),
#[cfg(not(feature = "_debug"))]
#[error(transparent)]
Serde(#[from] serde_json::Error),
#[cfg(feature = "_debug")]
#[error(transparent)]
Serde(#[from] serde_path_to_error::Error<serde_json::Error>),
#[error(transparent)]
MLB(#[from] MLBError),
}
pub trait RequestURL: ToString {
type Response: DeserializeOwned;
fn get(&self) -> impl Future<Output = Result<Self::Response>>
where
Self: Sized,
{
let url = self.to_string();
get::<Self::Response>(url)
}
}
pub trait RequestURLBuilderExt where Self: Sized {
type Built: RequestURL + From<Self>;
fn build_and_get(self) -> impl Future<Output = Result<<Self::Built as RequestURL>::Response>> {
async {
let built = Self::Built::from(self);
let url = built.to_string();
if cfg!(all(feature = "_debug", test)) {
println!("url = {url}");
}
get::<<Self::Built as RequestURL>::Response>(url).await
}
}
}