use crate::auth::auth_token;
use crate::constants::ENV_VAR_NAME;
use crate::https::{get_https_client, tls};
use crate::models::Media;
use crate::status::raise_for_status;
use crate::utils::into_struct_from_slice;
use crate::RustWistiaError;
use std::borrow::Cow;
use std::time::Instant;
use hyper::client::{Client, HttpConnector};
use hyper::header::AUTHORIZATION;
use hyper::{Body, Method, Request};
use log::debug;
use serde::de::DeserializeOwned;
pub type WistiaClient<'a> = DataClient<'a>;
pub struct DataClient<'a> {
pub access_token: Cow<'a, str>,
pub client: Client<tls::HttpsConnector<HttpConnector>>,
}
impl<'a> From<Cow<'a, str>> for DataClient<'a> {
fn from(access_token: Cow<'a, str>) -> Self {
let token = auth_token(&access_token);
Self {
access_token: Cow::Owned(token),
client: get_https_client(),
}
}
}
impl<'a> From<&'a str> for DataClient<'a> {
fn from(access_token: &'a str) -> Self {
Self::from(Cow::Borrowed(access_token))
}
}
impl<'a> From<String> for DataClient<'a> {
fn from(access_token: String) -> Self {
Self::from(Cow::Owned(access_token))
}
}
impl<'a> DataClient<'a> {
pub fn new(access_token: &'a str) -> Self {
Self::from(access_token)
}
pub fn from_env() -> crate::Result<Self> {
let token: String =
std::env::var(ENV_VAR_NAME).map_err(|_| RustWistiaError::EnvVarNotFound {
name: ENV_VAR_NAME.to_owned(),
})?;
Ok(Self::from(token))
}
pub async fn get_media(&self, video_id: &'a str) -> crate::Result<Media> {
let url = format!(
"https://api.wistia.com/v1/medias/{media_id}.json",
media_id = video_id
);
self.get(&url).await
}
pub async fn get<R: DeserializeOwned>(&'a self, url: &'a str) -> crate::Result<R> {
let token = self.access_token.as_ref();
let req = Request::builder()
.method(Method::GET)
.uri(url)
.header(AUTHORIZATION, token)
.body(Body::empty())?;
self.make_request(url, req).await
}
pub(crate) async fn make_request<R: DeserializeOwned>(
&'a self,
url: &'a str,
req: Request<Body>,
) -> crate::Result<R> {
let start = Instant::now();
let mut resp = self.client.request(req).await?;
debug!("Call Data API completed {:.2?}", start.elapsed());
raise_for_status(url, &mut resp).await?;
into_struct_from_slice(resp).await
}
}