diff options
author | David Blajda <blajda@hotmail.com> | 2018-12-17 05:35:19 +0000 |
---|---|---|
committer | David Blajda <blajda@hotmail.com> | 2018-12-17 05:35:19 +0000 |
commit | d9887360a2b015405abe550858391034e9dda9a1 (patch) | |
tree | ebf509b3b112c17ed9283c7a1a02de3e8da2a281 | |
parent | 23ea9413cd0e29eb451df08c5c799d64f56a1342 (diff) |
Figuring out how to implement auth and ratelimt barriers
-rw-r--r-- | src/helix/mod.rs | 83 | ||||
-rw-r--r-- | src/helix/namespaces/clips.rs | 20 |
2 files changed, 81 insertions, 22 deletions
diff --git a/src/helix/mod.rs b/src/helix/mod.rs index 650c4b0..0ddd910 100644 --- a/src/helix/mod.rs +++ b/src/helix/mod.rs @@ -33,6 +33,18 @@ impl<T> Namespace<T> { } } +#[derive(PartialEq, Hash, Eq, Clone)] +pub enum Scope { + AnalyticsReadExtensions, + AnalyticsReadGames, + BitsRead, + ClipsEdit, + UserEdit, + UserEditBroadcast, + UserReadBroadcast, + UserReadEmail, +} + #[derive(Clone)] pub struct Client { inner: Arc<ClientRef>, @@ -161,15 +173,66 @@ impl AuthClientBuilder { } } +use std::collections::BTreeMap; -#[derive(PartialEq, Hash, Eq, Clone)] -pub enum Scope { - AnalyticsReadExtensions, - AnalyticsReadGames, - BitsRead, - ClipsEdit, - UserEdit, - UserEditBroadcast, - UserReadBroadcast, - UserReadEmail, +enum RequestState<T> { + Uninitalized, + Polling(Box<dyn Future<Item=T, Error=reqwest::Error> + Send>) +} + +pub struct ApiRequest<T> { + url: String, + params: BTreeMap<String, String>, + client: Client, + state: RequestState<T>, +} + +impl<T: DeserializeOwned + 'static + Send> ApiRequest<T> { + + pub fn new(url: String, + params: BTreeMap<String, String>, + client: Client + ) -> ApiRequest<T> + { + ApiRequest { + url, + params, + client: client, + state: RequestState::Uninitalized + } + } +} + +use futures::Poll; +use serde::de::DeserializeOwned; +use futures::Async; +use futures::try_ready; + +impl<T: DeserializeOwned + 'static + Send> Future for ApiRequest<T> { + type Item = T; + type Error = reqwest::Error; + + fn poll(&mut self) -> Poll<Self::Item, Self::Error> { + loop { + match &mut self.state { + RequestState::Uninitalized => { + let request = self.client.client().get(&self.url); + let request = self.client.apply_standard_headers(request); + let request = request.query(&self.params); + + let f = request + .send() + .map(|mut res| { + res.json::<T>() + }) + .and_then(|json| json); + self.state = RequestState::Polling(Box::new(f)); + }, + RequestState::Polling(future) => { + let res = try_ready!(future.poll()); + return Ok(Async::Ready(res)); + } + } + } + } } diff --git a/src/helix/namespaces/clips.rs b/src/helix/namespaces/clips.rs index 32793c0..351f006 100644 --- a/src/helix/namespaces/clips.rs +++ b/src/helix/namespaces/clips.rs @@ -1,4 +1,5 @@ use futures::future::Future; +use std::collections::BTreeMap; use super::super::models::{DataContainer, PaginationContainer, User, Video, Clip}; use super::super::Client; const API_DOMAIN: &'static str = "api.twitch.tv"; @@ -8,7 +9,7 @@ pub struct Clips {} type ClipsNamespace = Namespace<Clips>; impl ClipsNamespace { - pub fn clip(self, id: &str) -> impl Future<Item=DataContainer<Clip>, Error=reqwest::Error> { + pub fn clip(self, id: &str) -> ApiRequest<DataContainer<Clip>> { use self::clip; clip(self.client, id) } @@ -21,22 +22,17 @@ impl Client { } } +use super::super::ApiRequest; + + pub fn clip(client: Client, id: &str) - -> impl Future<Item=DataContainer<Clip>, Error=reqwest::Error> + -> ApiRequest<DataContainer<Clip>> { let url = String::from("https://") + API_DOMAIN + "/helix/clips" + "?id=" + id; + let params = BTreeMap::new(); - let request = client.client().get(&url); - let request = client.apply_standard_headers(request); - - request - .send() - .map(|mut res| { - println!("{:?}", res); - res.json::<DataContainer<Clip>>() - }) - .and_then(|json| json) + ApiRequest::new( url, params, client) } |