diff options
author | David Blajda <blajda@hotmail.com> | 2018-12-10 19:11:29 +0000 |
---|---|---|
committer | David Blajda <blajda@hotmail.com> | 2018-12-10 19:11:29 +0000 |
commit | b58a38e8a2ec2598dadc6248100735ca46fd7b8f (patch) | |
tree | cebea99c566628b82ec22c187998d931f7b80b8b | |
parent | 9dd87f39a25c4fd719fd73530ff4a17ff0197808 (diff) |
Add video endpoint
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/bin/main.rs | 36 | ||||
-rw-r--r-- | src/lib.rs | 106 |
3 files changed, 104 insertions, 39 deletions
@@ -11,3 +11,4 @@ tokio = "0.1.13" dotenv = "0.13.0" serde = "1.0.81" serde_json = "1.0.33" +serde_derive = "1.0.81" diff --git a/src/bin/main.rs b/src/bin/main.rs index c995d4d..f2be7d8 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -1,23 +1,43 @@ -extern crate twitch_api; -extern crate tokio; extern crate dotenv; extern crate futures; extern crate serde; +extern crate tokio; +extern crate twitch_api; -use twitch_api::TwitchApi; -use std::env; use futures::future::Future; +use std::env; +use twitch_api::Client; fn main() { dotenv::dotenv().unwrap(); - let mut twitch_api = TwitchApi::new(env::var("TWITCH_API").unwrap()); - let mut users = twitch_api.users(vec![], vec!["shroud", "ninja"]) + let twitch_api = Client::new(&env::var("TWITCH_API").unwrap()); + + let users = twitch_api + .users(vec![], vec!["shroud", "ninja"]) .and_then(|json| { println!("{:?}", json); + println!("len {}", json.data.len()); Ok(json) }) .map(|_| ()) - .map_err(|_| ()); + .map_err(|err| { + println!("{:?}", err); + () + }); + + let videos = twitch_api + .videos(None, Some("37402112"), None) + .and_then(|json| { + println!("{:?}", json); + Ok(json) + }) + .map(|_| ()) + .map_err(|err| { + println!("{:?}", err); + () + }); + + - tokio::run(users); + tokio::run(users.join(videos).map(|_| ())); } @@ -1,32 +1,56 @@ -extern crate reqwest; extern crate futures; +extern crate reqwest; extern crate serde; -use reqwest::r#async::{Client, Request, Chunk, Response, Decoder}; -use reqwest::header; +#[macro_use] +extern crate serde_derive; + +pub mod models; + use futures::future::Future; -use std::iter::Iterator; -use futures::Stream; +use reqwest::header; +use reqwest::r#async::{Chunk, Decoder, Request, Response}; +use reqwest::r#async::Client as ReqwestClient; + +use self::models::{DataContainer, PaginationContainer, User, Video}; const API_DOMAIN: &'static str = "api.twitch.tv"; -pub struct TwitchApi { - client_id: String, +/* When Client owns a ReqwestClient, any futures spawned do not immediately + * terminate but 'hang'. When creating a new client for each request this problem + * does not occur. This would need to be resolved so we can benefit from keep alive + * connections. + * + */ + +pub struct Client { + id: String, } -impl TwitchApi { - pub fn new(client_id: String) -> TwitchApi { - TwitchApi { - client_id +impl Client { + pub fn new(client_id: &str) -> Client { + Client { + id: client_id.to_owned(), } } - pub fn users(&mut self, id: Vec<&str>, login: Vec<&str>) -> Box<Future<Item=serde_json::Value, Error=reqwest::Error> + Send> { + fn create_client(&self) -> ReqwestClient { let mut headers = header::HeaderMap::new(); - let auth_key = &self.client_id; - let header_value = header::HeaderValue::from_str(&auth_key).unwrap(); + let auth_key = &self.id; + let header_value = header::HeaderValue::from_str(auth_key).unwrap(); headers.insert("Client-ID", header_value); - let mut url = String::from("https://") + &String::from(API_DOMAIN) + &String::from("/helix/users"); + + let client = ReqwestClient::builder().default_headers(headers).build().unwrap(); + client + } + + pub fn users( + &self, + id: Vec<&str>, + login: Vec<&str>, + ) -> impl Future<Item = DataContainer<User>, Error = reqwest::Error> { + let mut url = + String::from("https://") + &String::from(API_DOMAIN) + &String::from("/helix/users"); if id.len() > 0 || login.len() > 0 { url.push_str("?"); @@ -48,21 +72,41 @@ impl TwitchApi { } } - let client = Client::builder() - .default_headers(headers) - .build().unwrap(); - - - let mut f = client - .get(&url) - .send() - .map(|mut res| { - res.json::<serde_json::Value>() - }) - .and_then(|json| { - json - }); - - return Box::new(f); + + let f = self.create_client() + .get(&url) + .send() + .map(|mut res| res.json::<DataContainer<User>>()) + .and_then(|json| json); + + return f; + } + + pub fn videos( + &self, + video_id: Option<Vec<&str>>, + user_id: Option<&str>, + game_id: Option<&str>, + ) -> impl Future<Item = PaginationContainer<Video>, Error = reqwest::Error> { + let mut url = + String::from("https://") + &String::from(API_DOMAIN) + &String::from("/helix/videos"); + + url.push_str("?"); + if let Some(user_id) = user_id { + url.push_str("user_id="); + url.push_str(user_id); + url.push('&'); + } + + let f = self.create_client() + .get(&url) + .send() + .map(|mut res| { + println!("{:?}", res); + res.json::<PaginationContainer<Video>>() + }) + .and_then(|json| json); + + return f; } } |