diff --git a/src/consts/champion.rs b/src/consts/champion.rs index cad8bf3..6cae740 100644 --- a/src/consts/champion.rs +++ b/src/consts/champion.rs @@ -1,7 +1,7 @@  // This file is automatically generated. // Do not directly edit. -// Generated on 2019-10-21T02:25:22.691Z +// Generated on 2019-10-22T04:47:08.742Z use std::fmt; use num_derive; diff --git a/src/dto.rs b/src/dto.rs index 5f07af2..b6dcf32 100644 --- a/src/dto.rs +++ b/src/dto.rs @@ -1,7 +1,7 @@ // This file is automatically generated. // Do not directly edit. -// Generated on 2019-10-21T02:25:22.768Z +// Generated on 2019-10-22T04:47:08.827Z // http://www.mingweisamuel.com/riotapi-schema/tool/ // Version 0c74167e0eaaeb6de1c7e8219fecaabcf8386d1f diff --git a/src/lib.rs b/src/lib.rs index 9b8e230..98a1798 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,6 @@ mod dto; pub use dto::*; -mod endpoints; -pub use endpoints::*; - pub mod consts; mod riot_api_config; @@ -41,11 +38,10 @@ mod tests { let champ = crate::consts::Champion::Riven; println!("{}", champ); - let api_key_raw = std::fs::read_to_string("apikey.txt").unwrap(); // TODO don't use unwrap. - let api_key = api_key_raw.trim(); + let api_key = std::fs::read_to_string("apikey.txt").unwrap(); // TODO don't use unwrap. let rt = Runtime::new().unwrap(); - let riot_api = RiotApi::with_key(api_key); + let riot_api = RiotApi::with_key(api_key.trim()); for i in 0..2 { let my_future = riot_api.champion_mastery_v4_get_all_champion_masteries( diff --git a/src/req/mod.rs b/src/req/mod.rs index 88c8e46..9bd0166 100644 --- a/src/req/mod.rs +++ b/src/req/mod.rs @@ -2,10 +2,10 @@ mod rate_limit; mod rate_limit_type; mod token_bucket; mod regional_requester; -mod requester_manager; +// mod requester_manager; pub use rate_limit::*; pub use rate_limit_type::*; pub use token_bucket::*; pub use regional_requester::*; -pub use requester_manager::*; +// pub use requester_manager::*; diff --git a/src/req/regional_requester.rs b/src/req/regional_requester.rs index becc70f..173ec87 100644 --- a/src/req/regional_requester.rs +++ b/src/req/regional_requester.rs @@ -1,3 +1,4 @@ +use std::future::Future; use std::sync::Arc; use reqwest::{ Client, StatusCode, Url }; @@ -10,19 +11,17 @@ use crate::util::InsertOnlyCHashMap; use super::RateLimit; use super::RateLimitType; -pub struct RegionalRequester<'a> { - /// Configuration settings. - riot_api_config: &'a RiotApiConfig<'a>, - /// Client for making requests. - client: &'a Client, +pub struct RegionalRequester { + + /// Represents the app rate limit. app_rate_limit: RateLimit, /// Represents method rate limits. - method_rate_limits: InsertOnlyCHashMap<&'a str, RateLimit>, + method_rate_limits: InsertOnlyCHashMap<&'static str, RateLimit>, } -impl<'a> RegionalRequester<'a> { +impl RegionalRequester { /// Request header name for the Riot API key. const RIOT_KEY_HEADER: &'static str = "X-Riot-Token"; @@ -30,79 +29,85 @@ impl<'a> RegionalRequester<'a> { const NONE_STATUS_CODES: [u16; 3] = [ 204, 404, 422 ]; - pub fn new(riot_api_config: &'a RiotApiConfig<'a>, client: &'a Client) -> Self { + pub fn new() -> Self { Self { - riot_api_config: riot_api_config, - client: client, app_rate_limit: RateLimit::new(RateLimitType::Application), method_rate_limits: InsertOnlyCHashMap::new(), } } - pub async fn get( - &self, method_id: &'a str, region: Region, path: &str, - query: Option<&str>) -> Result, reqwest::Error> + pub fn get<'a, T: serde::de::DeserializeOwned>(self: Arc, + config: &'a RiotApiConfig, client: &'a Client, + method_id: &'static str, region: Region, path: String, + query: Option) + -> impl Future, reqwest::Error>> + 'a { + async move { + let query = query.as_ref().map(|s| s.as_ref()); - let mut attempts: u8 = 0; - for _ in 0..=self.riot_api_config.retries { - attempts += 1; + // let ref config = RiotApiConfig::with_key("asdf"); + // let ref client = Client::new(); - let method_rate_limit: Arc = self.method_rate_limits - .get_or_insert_with(method_id, || RateLimit::new(RateLimitType::Method)); + let mut attempts: u8 = 0; + for _ in 0..=config.retries { + attempts += 1; - // Rate limiting. - while let Some(delay) = RateLimit::get_both_or_delay(&self.app_rate_limit, &*method_rate_limit) { - delay_for(delay).await; - } + let method_rate_limit: Arc = self.method_rate_limits + .get_or_insert_with(method_id, || RateLimit::new(RateLimitType::Method)); - // Send request. - let url_base = format!("https://{}.api.riotgames.com", region.platform); - let mut url = Url::parse(&*url_base) - .unwrap_or_else(|_| panic!("Failed to parse url_base: \"{}\".", url_base)); - url.set_path(path); - url.set_query(query); - - let result = self.client.get(url) - .header(Self::RIOT_KEY_HEADER, self.riot_api_config.api_key) - .send() - .await; - - let response = match result { - Err(e) => return Err(e), - Ok(r) => r, - }; - - // Maybe update rate limits (based on response headers). - self.app_rate_limit.on_response(&response); - method_rate_limit.on_response(&response); - - // Handle response. - let status = response.status(); - // Success, return None. - if Self::is_none_status_code(&status) { - return Ok(None); - } - // Success, return a value. - if status.is_success() { - let value = response.json::().await; - return match value { - Err(e) => Err(e), - Ok(v) => Ok(Some(v)), + // Rate limiting. + while let Some(delay) = RateLimit::get_both_or_delay(&self.app_rate_limit, &*method_rate_limit) { + delay_for(delay).await; } + + // Send request. + let url_base = format!("https://{}.api.riotgames.com", region.platform); + let mut url = Url::parse(&*url_base) + .unwrap_or_else(|_| panic!("Failed to parse url_base: \"{}\".", url_base)); + url.set_path(&*path); + url.set_query(query); + + let result = client.get(url) + .header(Self::RIOT_KEY_HEADER, &*config.api_key) + .send() + .await; + + let response = match result { + Err(e) => return Err(e), + Ok(r) => r, + }; + + // Maybe update rate limits (based on response headers). + self.app_rate_limit.on_response(&response); + method_rate_limit.on_response(&response); + + // Handle response. + let status = response.status(); + // Success, return None. + if Self::is_none_status_code(&status) { + return Ok(None); + } + // Success, return a value. + if status.is_success() { + let value = response.json::().await; + return match value { + Err(e) => Err(e), + Ok(v) => Ok(Some(v)), + } + } + // Retryable. + if StatusCode::TOO_MANY_REQUESTS == status || status.is_server_error() { + continue; + } + // Failure (non-retryable). + if status.is_client_error() { + break; + } + panic!("NOT HANDLED: {}!", status); } - // Retryable. - if StatusCode::TOO_MANY_REQUESTS == status || status.is_server_error() { - continue; - } - // Failure (non-retryable). - if status.is_client_error() { - break; - } - panic!("NOT HANDLED: {}!", status); + // TODO: return error. + panic!("FAILED AFTER {} ATTEMPTS!", attempts); } - // TODO: return error. - panic!("FAILED AFTER {} ATTEMPTS!", attempts); } fn is_none_status_code(status: &StatusCode) -> bool { diff --git a/src/req/requester_manager.rs b/src/req/requester_manager.rs index 5fceece..9fa7447 100644 --- a/src/req/requester_manager.rs +++ b/src/req/requester_manager.rs @@ -1,3 +1,5 @@ +use std::future::Future; + use log::*; use reqwest::Client; @@ -7,18 +9,18 @@ use crate::util::InsertOnlyCHashMap; use super::RegionalRequester; -pub struct RequesterManager<'a> { +pub struct RequesterManager { /// Configuration settings. - pub riot_api_config: RiotApiConfig<'a>, + riot_api_config: RiotApiConfig, /// Client for making requests. client: Client, /// Per-region requesters. - regional_requesters: InsertOnlyCHashMap>, + regional_requesters: InsertOnlyCHashMap, } -impl<'a> RequesterManager<'a> { - pub fn new(riot_api_config: RiotApiConfig<'a>) -> Self { +impl RequesterManager { + pub fn new(riot_api_config: RiotApiConfig) -> Self { // TODO configure client. let client = Client::new(); trace!("Creating client (TODO: configuration)."); @@ -30,13 +32,19 @@ impl<'a> RequesterManager<'a> { } } - pub async fn get( - &'a self, method_id: &'a str, region: Region, path: &str, - query: Option<&str>) -> Result, reqwest::Error> - { - // TODO: max concurrent requests? Or can configure client? - let regional_requester = self.regional_requesters - .get_or_insert_with(region, || RegionalRequester::new(&self.riot_api_config, &self.client)); - regional_requester.get(method_id, region, path, query).await + pub fn get_regional_requester(&self, region: Region) { + self.regional_requesters + .get_or_insert_with(region, || RegionalRequester::new()) } + + // pub fn get( + // &self, method_id: &'static str, region: Region, path: &str, + // query: Option<&str>) -> dyn Future, reqwest::Error>> + // { + // // TODO: max concurrent requests? Or can configure client? + // let regional_requester = self.regional_requesters + // .get_or_insert_with(region, || RegionalRequester::new()); + // regional_requester + // .get(&self.riot_api_config, &self.client, method_id, region, path, query) + // } } diff --git a/src/riot_api.rs b/src/riot_api.rs index 5240457..9917f61 100644 --- a/src/riot_api.rs +++ b/src/riot_api.rs @@ -1,21 +1,47 @@ -use crate::RiotApiConfig; -use crate::req::RequesterManager; +mod endpoints; +pub use endpoints::*; -pub struct RiotApi<'a> { - pub requester_manager: RequesterManager<'a>, - _private: (), +use std::future::Future; + +use log::*; +use reqwest::Client; + +use crate::RiotApiConfig; +use crate::consts::Region; +use crate::req::RegionalRequester; +use crate::util::InsertOnlyCHashMap; + +pub struct RiotApi { + /// Configuration settings. + config: RiotApiConfig, + /// Client for making requests. + client: Client, + + /// Per-region requesters. + regional_requesters: InsertOnlyCHashMap, } -impl<'a> RiotApi<'a> { - pub fn with_config(config: RiotApiConfig<'a>) -> Self { - let req_man = RequesterManager::new(config); +impl RiotApi { + pub fn with_config(config: RiotApiConfig) -> Self { + trace!("Creating client (TODO: configuration)."); Self { - requester_manager: req_man, - _private: (), + config: config, + client: Client::new(), + regional_requesters: InsertOnlyCHashMap::new(), } } - pub fn with_key(api_key: &'a str) -> Self { + pub fn with_key>(api_key: T) -> Self { Self::with_config(RiotApiConfig::with_key(api_key)) } + + pub fn get<'a, T: serde::de::DeserializeOwned + 'a>(&'a self, + method_id: &'static str, region: Region, path: String, query: Option) + -> impl Future, reqwest::Error>> + 'a + { + // TODO: max concurrent requests? Or can configure client? + self.regional_requesters + .get_or_insert_with(region, || RegionalRequester::new()) + .get(&self.config, &self.client, method_id, region, path, query) + } } diff --git a/src/endpoints.rs b/src/riot_api/endpoints.rs similarity index 64% rename from src/endpoints.rs rename to src/riot_api/endpoints.rs index 1432b1c..820d5cf 100644 --- a/src/endpoints.rs +++ b/src/riot_api/endpoints.rs @@ -1,11 +1,12 @@ // This file is automatically generated. // Do not directly edit. -// Generated on 2019-10-21T02:25:22.772Z +// Generated on 2019-10-22T04:47:08.813Z // http://www.mingweisamuel.com/riotapi-schema/tool/ // Version 0c74167e0eaaeb6de1c7e8219fecaabcf8386d1f +use std::future::Future; use std::vec::Vec; use reqwest; @@ -16,18 +17,18 @@ use crate::riot_api::RiotApi; // ChampionMasteryV4 -impl<'a> RiotApi<'a> { +impl RiotApi { /// Get all champion mastery entries sorted by number of champion points descending, /// # Official API Reference /// https://developer.riotgames.com/api-methods/#champion-mastery-v4/GET_getAllChampionMasteries /// # Parameters /// * `region` - Region to query. /// * `encryptedSummonerId` - Summoner ID associated with the player - pub async fn champion_mastery_v4_get_all_champion_masteries(&'a self, region: Region, encrypted_summoner_id: &str) -> Result>, reqwest::Error> { + pub fn champion_mastery_v4_get_all_champion_masteries<'a>(&'a self, region: Region, encrypted_summoner_id: &str) + -> impl Future>, reqwest::Error>> + 'a + { let path_string = format!("/lol/champion-mastery/v4/champion-masteries/by-summoner/{}", encrypted_summoner_id); - return self.requester_manager.get::>( - "champion-mastery-v4.getAllChampionMasteries", region, &*path_string, - None).await; // false); + self.get::>("champion-mastery-v4.getAllChampionMasteries", region, path_string, None) } /// Get a champion mastery by player ID and champion ID. @@ -37,11 +38,11 @@ impl<'a> RiotApi<'a> { /// * `region` - Region to query. /// * `championId` - Champion ID to retrieve Champion Mastery for /// * `encryptedSummonerId` - Summoner ID associated with the player - pub async fn champion_mastery_v4_get_champion_mastery(&'a self, region: Region, encrypted_summoner_id: &str, champion_id: i64) -> Result, reqwest::Error> { + pub fn champion_mastery_v4_get_champion_mastery<'a>(&'a self, region: Region, encrypted_summoner_id: &str, champion_id: i64) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/champion-mastery/v4/champion-masteries/by-summoner/{}/by-champion/{}", encrypted_summoner_id, champion_id); - return self.requester_manager.get::( - "champion-mastery-v4.getChampionMastery", region, &*path_string, - None).await; // false); + self.get::("champion-mastery-v4.getChampionMastery", region, path_string, None) } /// Get a player's total champion mastery score, which is the sum of individual champion mastery levels. @@ -50,33 +51,33 @@ impl<'a> RiotApi<'a> { /// # Parameters /// * `region` - Region to query. /// * `encryptedSummonerId` - Summoner ID associated with the player - pub async fn champion_mastery_v4_get_champion_mastery_score(&'a self, region: Region, encrypted_summoner_id: &str) -> Result, reqwest::Error> { + pub fn champion_mastery_v4_get_champion_mastery_score<'a>(&'a self, region: Region, encrypted_summoner_id: &str) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/champion-mastery/v4/scores/by-summoner/{}", encrypted_summoner_id); - return self.requester_manager.get::( - "champion-mastery-v4.getChampionMasteryScore", region, &*path_string, - None).await; // false); + self.get::("champion-mastery-v4.getChampionMasteryScore", region, path_string, None) } } // ChampionV3 -impl<'a> RiotApi<'a> { +impl RiotApi { /// Returns champion rotations, including free-to-play and low-level free-to-play rotations (REST) /// # Official API Reference /// https://developer.riotgames.com/api-methods/#champion-v3/GET_getChampionInfo /// # Parameters /// * `region` - Region to query. - pub async fn champion_v3_get_champion_info(&'a self, region: Region) -> Result, reqwest::Error> { - let path_string = "/lol/platform/v3/champion-rotations"; - return self.requester_manager.get::( - "champion-v3.getChampionInfo", region, &*path_string, - None).await; // false); + pub fn champion_v3_get_champion_info<'a>(&'a self, region: Region) + -> impl Future, reqwest::Error>> + 'a + { + let path_string = "/lol/platform/v3/champion-rotations".to_owned(); + self.get::("champion-v3.getChampionInfo", region, path_string, None) } } // LeagueExpV4 -impl<'a> RiotApi<'a> { +impl RiotApi { /// Get all the league entries. /// # Official API Reference /// https://developer.riotgames.com/api-methods/#league-exp-v4/GET_getLeagueEntries @@ -86,31 +87,31 @@ impl<'a> RiotApi<'a> { /// * `tier` /// * `division` /// * `page` (optional) - Starts with page 1. - pub async fn league_exp_v4_get_league_entries(&'a self, region: Region, division: &str, tier: &str, queue: &str, page: Option) -> Result>, reqwest::Error> { + pub fn league_exp_v4_get_league_entries<'a>(&'a self, region: Region, division: &str, tier: &str, queue: &str, page: Option) + -> impl Future>, reqwest::Error>> + 'a + { let mut query_params = Serializer::new(String::new()); if let Some(page) = page { query_params.append_pair("page", &*page.to_string()); }; let query_string = query_params.finish(); let path_string = format!("/lol/league-exp/v4/entries/{}/{}/{}", division, tier, queue); - return self.requester_manager.get::>( - "league-exp-v4.getLeagueEntries", region, &*path_string, - Some(&*query_string)).await; // false); + self.get::>("league-exp-v4.getLeagueEntries", region, path_string, Some(query_string)) } } // LeagueV4 -impl<'a> RiotApi<'a> { +impl RiotApi { /// Get the challenger league for given queue. /// # Official API Reference /// https://developer.riotgames.com/api-methods/#league-v4/GET_getChallengerLeague /// # Parameters /// * `region` - Region to query. /// * `queue` - pub async fn league_v4_get_challenger_league(&'a self, region: Region, queue: &str) -> Result, reqwest::Error> { + pub fn league_v4_get_challenger_league<'a>(&'a self, region: Region, queue: &str) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/league/v4/challengerleagues/by-queue/{}", queue); - return self.requester_manager.get::( - "league-v4.getChallengerLeague", region, &*path_string, - None).await; // false); + self.get::("league-v4.getChallengerLeague", region, path_string, None) } /// Get league entries in all queues for a given summoner ID. @@ -119,11 +120,11 @@ impl<'a> RiotApi<'a> { /// # Parameters /// * `region` - Region to query. /// * `encryptedSummonerId` - pub async fn league_v4_get_league_entries_for_summoner(&'a self, region: Region, encrypted_summoner_id: &str) -> Result>, reqwest::Error> { + pub fn league_v4_get_league_entries_for_summoner<'a>(&'a self, region: Region, encrypted_summoner_id: &str) + -> impl Future>, reqwest::Error>> + 'a + { let path_string = format!("/lol/league/v4/entries/by-summoner/{}", encrypted_summoner_id); - return self.requester_manager.get::>( - "league-v4.getLeagueEntriesForSummoner", region, &*path_string, - None).await; // false); + self.get::>("league-v4.getLeagueEntriesForSummoner", region, path_string, None) } /// Get all the league entries. @@ -135,14 +136,14 @@ impl<'a> RiotApi<'a> { /// * `tier` /// * `queue` - Note that the queue value must be a valid ranked queue. /// * `page` (optional) - Starts with page 1. - pub async fn league_v4_get_league_entries(&'a self, region: Region, queue: &str, tier: &str, division: &str, page: Option) -> Result>, reqwest::Error> { + pub fn league_v4_get_league_entries<'a>(&'a self, region: Region, queue: &str, tier: &str, division: &str, page: Option) + -> impl Future>, reqwest::Error>> + 'a + { let mut query_params = Serializer::new(String::new()); if let Some(page) = page { query_params.append_pair("page", &*page.to_string()); }; let query_string = query_params.finish(); let path_string = format!("/lol/league/v4/entries/{}/{}/{}", queue, tier, division); - return self.requester_manager.get::>( - "league-v4.getLeagueEntries", region, &*path_string, - Some(&*query_string)).await; // false); + self.get::>("league-v4.getLeagueEntries", region, path_string, Some(query_string)) } /// Get the grandmaster league of a specific queue. @@ -151,11 +152,11 @@ impl<'a> RiotApi<'a> { /// # Parameters /// * `region` - Region to query. /// * `queue` - pub async fn league_v4_get_grandmaster_league(&'a self, region: Region, queue: &str) -> Result, reqwest::Error> { + pub fn league_v4_get_grandmaster_league<'a>(&'a self, region: Region, queue: &str) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/league/v4/grandmasterleagues/by-queue/{}", queue); - return self.requester_manager.get::( - "league-v4.getGrandmasterLeague", region, &*path_string, - None).await; // false); + self.get::("league-v4.getGrandmasterLeague", region, path_string, None) } /// Get league with given ID, including inactive entries. @@ -164,11 +165,11 @@ impl<'a> RiotApi<'a> { /// # Parameters /// * `region` - Region to query. /// * `leagueId` - The UUID of the league. - pub async fn league_v4_get_league_by_id(&'a self, region: Region, league_id: &str) -> Result, reqwest::Error> { + pub fn league_v4_get_league_by_id<'a>(&'a self, region: Region, league_id: &str) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/league/v4/leagues/{}", league_id); - return self.requester_manager.get::( - "league-v4.getLeagueById", region, &*path_string, - None).await; // false); + self.get::("league-v4.getLeagueById", region, path_string, None) } /// Get the master league for given queue. @@ -177,17 +178,17 @@ impl<'a> RiotApi<'a> { /// # Parameters /// * `region` - Region to query. /// * `queue` - pub async fn league_v4_get_master_league(&'a self, region: Region, queue: &str) -> Result, reqwest::Error> { + pub fn league_v4_get_master_league<'a>(&'a self, region: Region, queue: &str) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/league/v4/masterleagues/by-queue/{}", queue); - return self.requester_manager.get::( - "league-v4.getMasterLeague", region, &*path_string, - None).await; // false); + self.get::("league-v4.getMasterLeague", region, path_string, None) } } // LolStatusV3 -impl<'a> RiotApi<'a> { +impl RiotApi { /// Get League of Legends status for the given shard. /// ## Rate Limit Notes /// Requests to this API are not counted against the application Rate Limits. @@ -195,28 +196,28 @@ impl<'a> RiotApi<'a> { /// https://developer.riotgames.com/api-methods/#lol-status-v3/GET_getShardData /// # Parameters /// * `region` - Region to query. - pub async fn lol_status_v3_get_shard_data(&'a self, region: Region) -> Result, reqwest::Error> { - let path_string = "/lol/status/v3/shard-data"; - return self.requester_manager.get::( - "lol-status-v3.getShardData", region, &*path_string, - None).await; // true); + pub fn lol_status_v3_get_shard_data<'a>(&'a self, region: Region) + -> impl Future, reqwest::Error>> + 'a + { + let path_string = "/lol/status/v3/shard-data".to_owned(); + self.get::("lol-status-v3.getShardData", region, path_string, None) } } // MatchV4 -impl<'a> RiotApi<'a> { +impl RiotApi { /// Get match IDs by tournament code. /// # Official API Reference /// https://developer.riotgames.com/api-methods/#match-v4/GET_getMatchIdsByTournamentCode /// # Parameters /// * `region` - Region to query. /// * `tournamentCode` - The tournament code. - pub async fn match_v4_get_match_ids_by_tournament_code(&'a self, region: Region, tournament_code: &str) -> Result>, reqwest::Error> { + pub fn match_v4_get_match_ids_by_tournament_code<'a>(&'a self, region: Region, tournament_code: &str) + -> impl Future>, reqwest::Error>> + 'a + { let path_string = format!("/lol/match/v4/matches/by-tournament-code/{}/ids", tournament_code); - return self.requester_manager.get::>( - "match-v4.getMatchIdsByTournamentCode", region, &*path_string, - None).await; // false); + self.get::>("match-v4.getMatchIdsByTournamentCode", region, path_string, None) } /// Get match by match ID. @@ -225,11 +226,11 @@ impl<'a> RiotApi<'a> { /// # Parameters /// * `region` - Region to query. /// * `matchId` - The match ID. - pub async fn match_v4_get_match(&'a self, region: Region, match_id: i64) -> Result, reqwest::Error> { + pub fn match_v4_get_match<'a>(&'a self, region: Region, match_id: i64) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/match/v4/matches/{}", match_id); - return self.requester_manager.get::( - "match-v4.getMatch", region, &*path_string, - None).await; // false); + self.get::("match-v4.getMatch", region, path_string, None) } /// Get match by match ID and tournament code. @@ -239,11 +240,11 @@ impl<'a> RiotApi<'a> { /// * `region` - Region to query. /// * `tournamentCode` - The tournament code. /// * `matchId` - The match ID. - pub async fn match_v4_get_match_by_tournament_code(&'a self, region: Region, match_id: i64, tournament_code: &str) -> Result, reqwest::Error> { + pub fn match_v4_get_match_by_tournament_code<'a>(&'a self, region: Region, match_id: i64, tournament_code: &str) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/match/v4/matches/{}/by-tournament-code/{}", match_id, tournament_code); - return self.requester_manager.get::( - "match-v4.getMatchByTournamentCode", region, &*path_string, - None).await; // false); + self.get::("match-v4.getMatchByTournamentCode", region, path_string, None) } /// Get matchlist for games played on given account ID and platform ID and filtered using given filter parameters, if any. @@ -265,7 +266,9 @@ impl<'a> RiotApi<'a> { /// * `beginTime` (optional) - The begin time to use for filtering matchlist specified as epoch milliseconds. If beginTime is specified, but not endTime, then endTime defaults to the the current unix timestamp in milliseconds (the maximum time range limitation is not observed in this specific case). If endTime is specified, but not beginTime, then beginTime defaults to the start of the account's match history returning a 400 due to the maximum time range limitation. If both are specified, then endTime should be greater than beginTime. The maximum time range allowed is one week, otherwise a 400 error code is returned. /// * `endIndex` (optional) - The end index to use for filtering matchlist. If beginIndex is specified, but not endIndex, then endIndex defaults to beginIndex+100. If endIndex is specified, but not beginIndex, then beginIndex defaults to 0. If both are specified, then endIndex must be greater than beginIndex. The maximum range allowed is 100, otherwise a 400 error code is returned. /// * `beginIndex` (optional) - The begin index to use for filtering matchlist. If beginIndex is specified, but not endIndex, then endIndex defaults to beginIndex+100. If endIndex is specified, but not beginIndex, then beginIndex defaults to 0. If both are specified, then endIndex must be greater than beginIndex. The maximum range allowed is 100, otherwise a 400 error code is returned. - pub async fn match_v4_get_matchlist(&'a self, region: Region, encrypted_account_id: &str, champion: Option>, queue: Option>, season: Option>, end_time: Option, begin_time: Option, end_index: Option, begin_index: Option) -> Result, reqwest::Error> { + pub fn match_v4_get_matchlist<'a>(&'a self, region: Region, encrypted_account_id: &str, champion: Option>, queue: Option>, season: Option>, end_time: Option, begin_time: Option, end_index: Option, begin_index: Option) + -> impl Future, reqwest::Error>> + 'a + { let mut query_params = Serializer::new(String::new()); if let Some(champion) = champion { query_params.extend_pairs(champion.iter().map(|w| ("champion", w.to_string()))); }; if let Some(queue) = queue { query_params.extend_pairs(queue.iter().map(|w| ("queue", w.to_string()))); }; @@ -276,9 +279,7 @@ impl<'a> RiotApi<'a> { if let Some(begin_index) = begin_index { query_params.append_pair("beginIndex", &*begin_index.to_string()); }; let query_string = query_params.finish(); let path_string = format!("/lol/match/v4/matchlists/by-account/{}", encrypted_account_id); - return self.requester_manager.get::( - "match-v4.getMatchlist", region, &*path_string, - Some(&*query_string)).await; // false); + self.get::("match-v4.getMatchlist", region, path_string, Some(query_string)) } /// Get match timeline by match ID. @@ -289,28 +290,28 @@ impl<'a> RiotApi<'a> { /// # Parameters /// * `region` - Region to query. /// * `matchId` - The match ID. - pub async fn match_v4_get_match_timeline(&'a self, region: Region, match_id: i64) -> Result, reqwest::Error> { + pub fn match_v4_get_match_timeline<'a>(&'a self, region: Region, match_id: i64) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/match/v4/timelines/by-match/{}", match_id); - return self.requester_manager.get::( - "match-v4.getMatchTimeline", region, &*path_string, - None).await; // false); + self.get::("match-v4.getMatchTimeline", region, path_string, None) } } // SpectatorV4 -impl<'a> RiotApi<'a> { +impl RiotApi { /// Get current game information for the given summoner ID. /// # Official API Reference /// https://developer.riotgames.com/api-methods/#spectator-v4/GET_getCurrentGameInfoBySummoner /// # Parameters /// * `region` - Region to query. /// * `encryptedSummonerId` - The ID of the summoner. - pub async fn spectator_v4_get_current_game_info_by_summoner(&'a self, region: Region, encrypted_summoner_id: &str) -> Result, reqwest::Error> { + pub fn spectator_v4_get_current_game_info_by_summoner<'a>(&'a self, region: Region, encrypted_summoner_id: &str) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/spectator/v4/active-games/by-summoner/{}", encrypted_summoner_id); - return self.requester_manager.get::( - "spectator-v4.getCurrentGameInfoBySummoner", region, &*path_string, - None).await; // false); + self.get::("spectator-v4.getCurrentGameInfoBySummoner", region, path_string, None) } /// Get list of featured games. @@ -318,28 +319,28 @@ impl<'a> RiotApi<'a> { /// https://developer.riotgames.com/api-methods/#spectator-v4/GET_getFeaturedGames /// # Parameters /// * `region` - Region to query. - pub async fn spectator_v4_get_featured_games(&'a self, region: Region) -> Result, reqwest::Error> { - let path_string = "/lol/spectator/v4/featured-games"; - return self.requester_manager.get::( - "spectator-v4.getFeaturedGames", region, &*path_string, - None).await; // false); + pub fn spectator_v4_get_featured_games<'a>(&'a self, region: Region) + -> impl Future, reqwest::Error>> + 'a + { + let path_string = "/lol/spectator/v4/featured-games".to_owned(); + self.get::("spectator-v4.getFeaturedGames", region, path_string, None) } } // SummonerV4 -impl<'a> RiotApi<'a> { +impl RiotApi { /// Get a summoner by account ID. /// # Official API Reference /// https://developer.riotgames.com/api-methods/#summoner-v4/GET_getByAccountId /// # Parameters /// * `region` - Region to query. /// * `encryptedAccountId` - pub async fn summoner_v4_get_by_account_id(&'a self, region: Region, encrypted_account_id: &str) -> Result, reqwest::Error> { + pub fn summoner_v4_get_by_account_id<'a>(&'a self, region: Region, encrypted_account_id: &str) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/summoner/v4/summoners/by-account/{}", encrypted_account_id); - return self.requester_manager.get::( - "summoner-v4.getByAccountId", region, &*path_string, - None).await; // false); + self.get::("summoner-v4.getByAccountId", region, path_string, None) } /// Get a summoner by summoner name. @@ -348,11 +349,11 @@ impl<'a> RiotApi<'a> { /// # Parameters /// * `region` - Region to query. /// * `summonerName` - Summoner Name - pub async fn summoner_v4_get_by_summoner_name(&'a self, region: Region, summoner_name: &str) -> Result, reqwest::Error> { + pub fn summoner_v4_get_by_summoner_name<'a>(&'a self, region: Region, summoner_name: &str) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/summoner/v4/summoners/by-name/{}", summoner_name); - return self.requester_manager.get::( - "summoner-v4.getBySummonerName", region, &*path_string, - None).await; // false); + self.get::("summoner-v4.getBySummonerName", region, path_string, None) } /// Get a summoner by PUUID. @@ -361,11 +362,11 @@ impl<'a> RiotApi<'a> { /// # Parameters /// * `region` - Region to query. /// * `encryptedPUUID` - Summoner ID - pub async fn summoner_v4_get_by_puuid(&'a self, region: Region, encrypted_puuid: &str) -> Result, reqwest::Error> { + pub fn summoner_v4_get_by_puuid<'a>(&'a self, region: Region, encrypted_puuid: &str) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/summoner/v4/summoners/by-puuid/{}", encrypted_puuid); - return self.requester_manager.get::( - "summoner-v4.getByPUUID", region, &*path_string, - None).await; // false); + self.get::("summoner-v4.getByPUUID", region, path_string, None) } /// Get a summoner by summoner ID. @@ -374,62 +375,62 @@ impl<'a> RiotApi<'a> { /// # Parameters /// * `region` - Region to query. /// * `encryptedSummonerId` - Summoner ID - pub async fn summoner_v4_get_by_summoner_id(&'a self, region: Region, encrypted_summoner_id: &str) -> Result, reqwest::Error> { + pub fn summoner_v4_get_by_summoner_id<'a>(&'a self, region: Region, encrypted_summoner_id: &str) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/summoner/v4/summoners/{}", encrypted_summoner_id); - return self.requester_manager.get::( - "summoner-v4.getBySummonerId", region, &*path_string, - None).await; // false); + self.get::("summoner-v4.getBySummonerId", region, path_string, None) } } // ThirdPartyCodeV4 -impl<'a> RiotApi<'a> { +impl RiotApi { /// Get third party code for a given summoner ID. /// # Official API Reference /// https://developer.riotgames.com/api-methods/#third-party-code-v4/GET_getThirdPartyCodeBySummonerId /// # Parameters /// * `region` - Region to query. /// * `encryptedSummonerId` - pub async fn third_party_code_v4_get_third_party_code_by_summoner_id(&'a self, region: Region, encrypted_summoner_id: &str) -> Result, reqwest::Error> { + pub fn third_party_code_v4_get_third_party_code_by_summoner_id<'a>(&'a self, region: Region, encrypted_summoner_id: &str) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/platform/v4/third-party-code/by-summoner/{}", encrypted_summoner_id); - return self.requester_manager.get::( - "third-party-code-v4.getThirdPartyCodeBySummonerId", region, &*path_string, - None).await; // false); + self.get::("third-party-code-v4.getThirdPartyCodeBySummonerId", region, path_string, None) } } // TournamentStubV4 -impl<'a> RiotApi<'a> { +impl RiotApi { /// Gets a mock list of lobby events by tournament code. /// # Official API Reference /// https://developer.riotgames.com/api-methods/#tournament-stub-v4/GET_getLobbyEventsByCode /// # Parameters /// * `region` - Region to query. /// * `tournamentCode` - The short code to look up lobby events for - pub async fn tournament_stub_v4_get_lobby_events_by_code(&'a self, region: Region, tournament_code: &str) -> Result, reqwest::Error> { + pub fn tournament_stub_v4_get_lobby_events_by_code<'a>(&'a self, region: Region, tournament_code: &str) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/tournament-stub/v4/lobby-events/by-code/{}", tournament_code); - return self.requester_manager.get::( - "tournament-stub-v4.getLobbyEventsByCode", region, &*path_string, - None).await; // false); + self.get::("tournament-stub-v4.getLobbyEventsByCode", region, path_string, None) } } // TournamentV4 -impl<'a> RiotApi<'a> { +impl RiotApi { /// Returns the tournament code DTO associated with a tournament code string. /// # Official API Reference /// https://developer.riotgames.com/api-methods/#tournament-v4/GET_getTournamentCode /// # Parameters /// * `region` - Region to query. /// * `tournamentCode` - The tournament code string. - pub async fn tournament_v4_get_tournament_code(&'a self, region: Region, tournament_code: &str) -> Result, reqwest::Error> { + pub fn tournament_v4_get_tournament_code<'a>(&'a self, region: Region, tournament_code: &str) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/tournament/v4/codes/{}", tournament_code); - return self.requester_manager.get::( - "tournament-v4.getTournamentCode", region, &*path_string, - None).await; // false); + self.get::("tournament-v4.getTournamentCode", region, path_string, None) } /// Gets a list of lobby events by tournament code. @@ -438,11 +439,11 @@ impl<'a> RiotApi<'a> { /// # Parameters /// * `region` - Region to query. /// * `tournamentCode` - The short code to look up lobby events for - pub async fn tournament_v4_get_lobby_events_by_code(&'a self, region: Region, tournament_code: &str) -> Result, reqwest::Error> { + pub fn tournament_v4_get_lobby_events_by_code<'a>(&'a self, region: Region, tournament_code: &str) + -> impl Future, reqwest::Error>> + 'a + { let path_string = format!("/lol/tournament/v4/lobby-events/by-code/{}", tournament_code); - return self.requester_manager.get::( - "tournament-v4.getLobbyEventsByCode", region, &*path_string, - None).await; // false); + self.get::("tournament-v4.getLobbyEventsByCode", region, path_string, None) } } diff --git a/src/riot_api_config.rs b/src/riot_api_config.rs index d5f8a60..f1e7a50 100644 --- a/src/riot_api_config.rs +++ b/src/riot_api_config.rs @@ -1,13 +1,13 @@ #[derive(Debug)] -pub struct RiotApiConfig<'a> { - pub api_key: &'a str, +pub struct RiotApiConfig { + pub api_key: String, pub retries: u8, } -impl<'a> RiotApiConfig<'a> { - pub fn with_key(api_key: &'a str) -> Self { +impl RiotApiConfig { + pub fn with_key>(api_key: T) -> Self { Self { - api_key: api_key, + api_key: api_key.into(), retries: 3 // TODO defaults. } } diff --git a/srcgen/dotUtils.js b/srcgen/dotUtils.js index d35de49..1f019b0 100644 --- a/srcgen/dotUtils.js +++ b/srcgen/dotUtils.js @@ -100,7 +100,7 @@ function formatAddQueryParam(param) { function formatRouteArgument(route, pathParams = []) { if (!pathParams.length) - return `"${route}"`; + return `"${route}".to_owned()`; route = route.replace(/\{\S+?\}/g, '{}'); const args = pathParams diff --git a/srcgen/endpoints.rs.dt b/srcgen/riot_api/endpoints.rs.dt similarity index 87% rename from srcgen/endpoints.rs.dt rename to srcgen/riot_api/endpoints.rs.dt index 689905c..70c676e 100644 --- a/srcgen/endpoints.rs.dt +++ b/srcgen/riot_api/endpoints.rs.dt @@ -9,6 +9,7 @@ // http://www.mingweisamuel.com/riotapi-schema/tool/ // Version {{= spec.info.version }} +use std::future::Future; use std::vec::Vec; use reqwest; @@ -30,7 +31,7 @@ use crate::riot_api::RiotApi; }} // {{= endpoint }} -impl<'a> RiotApi<'a> { +impl RiotApi { {{ for (let [ route, path ] of endpointMethods) { @@ -105,7 +106,9 @@ impl<'a> RiotApi<'a> { } } }} - pub async fn {{= dotUtils.changeCase.snakeCase(endpoint) }}_{{= method }}(&'a self, region: Region{{= argBuilder.join('') }}) -> Result, reqwest::Error> { + pub fn {{= dotUtils.changeCase.snakeCase(endpoint) }}_{{= method }}<'a>(&'a self, region: Region{{= argBuilder.join('') }}) + -> impl Future, reqwest::Error>> + 'a + { {{? queryParams.length }} let mut query_params = Serializer::new(String::new()); {{ @@ -119,9 +122,7 @@ impl<'a> RiotApi<'a> { let query_string = query_params.finish(); {{?}} let path_string = {{= routeArgument }}; - return self.requester_manager.get::<{{= returnType }}>( - "{{= operationId }}", region, &*path_string, - {{= queryParams.length ? 'Some(&*query_string)' : 'None' }}).await; // {{= rateLimitExcluded }}); + self.get::<{{= returnType }}>("{{= operationId }}", region, path_string, {{= queryParams.length ? 'Some(query_string)' : 'None' }}) } {{