forked from mirror/Riven
Compare commits
3 commits
v/2.x.x
...
users/ming
Author | SHA1 | Date | |
---|---|---|---|
|
41ef6d9c2e | ||
|
5d2925c0fa | ||
|
f716a30e31 |
12 changed files with 248 additions and 156 deletions
26
src/client/client.rs
Normal file
26
src/client/client.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use std::future::Future;
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
|
|
||||||
|
pub type BoxFut<T> = Pin<Box<dyn Future<Output = T> + Send>>;
|
||||||
|
|
||||||
|
pub trait Client {
|
||||||
|
type Resp: Response;
|
||||||
|
type Err: Debug;
|
||||||
|
fn new() -> Self;
|
||||||
|
fn get(&self, url_base: String, url_path: &str, url_query: Option<&str>,
|
||||||
|
headers: Vec<(&'static str, &str)>) -> BoxFut<Result<Self::Resp, <Self::Resp as Response>::Err>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: custom/generic HeaderValue trait? And for keys?
|
||||||
|
pub trait Response {
|
||||||
|
type Err: Debug;
|
||||||
|
fn status(&self) -> u16;
|
||||||
|
fn verison(&self) -> String;
|
||||||
|
fn header(&self, key: &str) -> Option<String>;
|
||||||
|
fn headers_all(&self, key: &str) -> Vec<String>;
|
||||||
|
fn into_body(self) -> BoxFut<Result<String, Self::Err>>;
|
||||||
|
fn into_json<T: DeserializeOwned + 'static>(self) -> BoxFut<Result<T, Self::Err>>;
|
||||||
|
}
|
62
src/client/client_reqwest.rs
Normal file
62
src/client/client_reqwest.rs
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
use std::iter::FromIterator;
|
||||||
|
use std::convert::TryInto;
|
||||||
|
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
|
|
||||||
|
use super::{ Client, Response, BoxFut };
|
||||||
|
|
||||||
|
impl Client for reqwest::Client {
|
||||||
|
type Resp = reqwest::Response;
|
||||||
|
type Err = reqwest::Error;
|
||||||
|
fn new() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
fn get(&self, url_base: String, url_path: &str, url_query: Option<&str>,
|
||||||
|
headers: Vec<(&'static str, &str)>) -> BoxFut<Result<reqwest::Response, reqwest::Error>>
|
||||||
|
{
|
||||||
|
let mut url = reqwest::Url::parse(&*url_base)
|
||||||
|
.unwrap_or_else(|_| panic!("Failed to parse url_base: \"{}\".", url_base));
|
||||||
|
url.set_path(url_path);
|
||||||
|
url.set_query(url_query);
|
||||||
|
|
||||||
|
let header_iter = headers.into_iter()
|
||||||
|
.map(|(key, value)| (
|
||||||
|
key.try_into().unwrap_or_else(|_| panic!("Invalid header key: \"{}\".", key)),
|
||||||
|
value.try_into().unwrap_or_else(|_| panic!("Invalid header value: \"{}\".", value)),
|
||||||
|
));
|
||||||
|
let header_map = reqwest::header::HeaderMap::from_iter(header_iter);
|
||||||
|
|
||||||
|
let fut = self.get(url)
|
||||||
|
.headers(header_map)
|
||||||
|
.send();
|
||||||
|
return Box::pin(fut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Response for reqwest::Response {
|
||||||
|
type Err = reqwest::Error;
|
||||||
|
fn status(&self) -> u16 {
|
||||||
|
self.status().as_u16()
|
||||||
|
}
|
||||||
|
fn verison(&self) -> String {
|
||||||
|
format!("{:?}", self.version())
|
||||||
|
}
|
||||||
|
fn header(&self, key: &str) -> Option<String> {
|
||||||
|
self.headers().get(key)
|
||||||
|
.and_then(|value| value.to_str().ok())
|
||||||
|
.map(|value| value.to_owned())
|
||||||
|
}
|
||||||
|
fn headers_all(&self, key: &str) -> Vec<String> {
|
||||||
|
self.headers().get_all(key).iter()
|
||||||
|
.filter_map(|value| value.to_str().ok())
|
||||||
|
.map(|value| value.to_owned())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
fn into_body(self) -> BoxFut<Result<String, reqwest::Error>> {
|
||||||
|
//buf: Vec<u8> = Vec::with_capacity(self.content_length());
|
||||||
|
Box::pin(self.text())
|
||||||
|
}
|
||||||
|
fn into_json<T: DeserializeOwned + 'static>(self) -> BoxFut<Result<T, reqwest::Error>> {
|
||||||
|
Box::pin(self.json())
|
||||||
|
}
|
||||||
|
}
|
7
src/client/mod.rs
Normal file
7
src/client/mod.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
///! Contains client support for `reqwest` and `surf`.
|
||||||
|
|
||||||
|
mod client;
|
||||||
|
pub use client::*;
|
||||||
|
|
||||||
|
mod client_reqwest;
|
||||||
|
pub use client_reqwest::*;
|
135
src/endpoints.rs
135
src/endpoints.rs
|
@ -7,7 +7,7 @@
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
||||||
// Version 71bb788ab92c0b03d5dd284402d9514b625fe2a4
|
// Version 64f3c82d132f12808d8eb8f483d1d2182386c432
|
||||||
|
|
||||||
//! Automatically generated endpoint handles.
|
//! Automatically generated endpoint handles.
|
||||||
|
|
||||||
|
@ -19,17 +19,18 @@ use std::vec::Vec;
|
||||||
use url::form_urlencoded::Serializer;
|
use url::form_urlencoded::Serializer;
|
||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
use crate::client::Client;
|
||||||
use crate::consts::Region;
|
use crate::consts::Region;
|
||||||
use crate::riot_api::RiotApi;
|
use crate::riot_api::RiotApi;
|
||||||
|
|
||||||
impl RiotApi {
|
impl<C: Client> RiotApi<C> {
|
||||||
/// Returns a handle for accessing [ChampionMasteryV4](crate::endpoints::ChampionMasteryV4) endpoints.
|
/// Returns a handle for accessing [ChampionMasteryV4](crate::endpoints::ChampionMasteryV4) endpoints.
|
||||||
/// # Riot Developer API Reference
|
/// # Riot Developer API Reference
|
||||||
/// <a href="https://developer.riotgames.com/apis#champion-mastery-v4" target="_blank">`champion-mastery-v4`</a>
|
/// <a href="https://developer.riotgames.com/apis#champion-mastery-v4" target="_blank">`champion-mastery-v4`</a>
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn champion_mastery_v4(&self) -> ChampionMasteryV4 {
|
pub fn champion_mastery_v4(&self) -> ChampionMasteryV4<C> {
|
||||||
ChampionMasteryV4 { base: self }
|
ChampionMasteryV4 { base: self }
|
||||||
}
|
}
|
||||||
/// Returns a handle for accessing [ChampionV3](crate::endpoints::ChampionV3) endpoints.
|
/// Returns a handle for accessing [ChampionV3](crate::endpoints::ChampionV3) endpoints.
|
||||||
|
@ -38,7 +39,7 @@ impl RiotApi {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn champion_v3(&self) -> ChampionV3 {
|
pub fn champion_v3(&self) -> ChampionV3<C> {
|
||||||
ChampionV3 { base: self }
|
ChampionV3 { base: self }
|
||||||
}
|
}
|
||||||
/// Returns a handle for accessing [ClashV1](crate::endpoints::ClashV1) endpoints.
|
/// Returns a handle for accessing [ClashV1](crate::endpoints::ClashV1) endpoints.
|
||||||
|
@ -47,7 +48,7 @@ impl RiotApi {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn clash_v1(&self) -> ClashV1 {
|
pub fn clash_v1(&self) -> ClashV1<C> {
|
||||||
ClashV1 { base: self }
|
ClashV1 { base: self }
|
||||||
}
|
}
|
||||||
/// Returns a handle for accessing [LeagueExpV4](crate::endpoints::LeagueExpV4) endpoints.
|
/// Returns a handle for accessing [LeagueExpV4](crate::endpoints::LeagueExpV4) endpoints.
|
||||||
|
@ -56,7 +57,7 @@ impl RiotApi {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn league_exp_v4(&self) -> LeagueExpV4 {
|
pub fn league_exp_v4(&self) -> LeagueExpV4<C> {
|
||||||
LeagueExpV4 { base: self }
|
LeagueExpV4 { base: self }
|
||||||
}
|
}
|
||||||
/// Returns a handle for accessing [LeagueV4](crate::endpoints::LeagueV4) endpoints.
|
/// Returns a handle for accessing [LeagueV4](crate::endpoints::LeagueV4) endpoints.
|
||||||
|
@ -65,7 +66,7 @@ impl RiotApi {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn league_v4(&self) -> LeagueV4 {
|
pub fn league_v4(&self) -> LeagueV4<C> {
|
||||||
LeagueV4 { base: self }
|
LeagueV4 { base: self }
|
||||||
}
|
}
|
||||||
/// Returns a handle for accessing [LolStatusV3](crate::endpoints::LolStatusV3) endpoints.
|
/// Returns a handle for accessing [LolStatusV3](crate::endpoints::LolStatusV3) endpoints.
|
||||||
|
@ -74,7 +75,7 @@ impl RiotApi {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn lol_status_v3(&self) -> LolStatusV3 {
|
pub fn lol_status_v3(&self) -> LolStatusV3<C> {
|
||||||
LolStatusV3 { base: self }
|
LolStatusV3 { base: self }
|
||||||
}
|
}
|
||||||
/// Returns a handle for accessing [LorRankedV1](crate::endpoints::LorRankedV1) endpoints.
|
/// Returns a handle for accessing [LorRankedV1](crate::endpoints::LorRankedV1) endpoints.
|
||||||
|
@ -83,7 +84,7 @@ impl RiotApi {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn lor_ranked_v1(&self) -> LorRankedV1 {
|
pub fn lor_ranked_v1(&self) -> LorRankedV1<C> {
|
||||||
LorRankedV1 { base: self }
|
LorRankedV1 { base: self }
|
||||||
}
|
}
|
||||||
/// Returns a handle for accessing [MatchV4](crate::endpoints::MatchV4) endpoints.
|
/// Returns a handle for accessing [MatchV4](crate::endpoints::MatchV4) endpoints.
|
||||||
|
@ -92,7 +93,7 @@ impl RiotApi {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn match_v4(&self) -> MatchV4 {
|
pub fn match_v4(&self) -> MatchV4<C> {
|
||||||
MatchV4 { base: self }
|
MatchV4 { base: self }
|
||||||
}
|
}
|
||||||
/// Returns a handle for accessing [SpectatorV4](crate::endpoints::SpectatorV4) endpoints.
|
/// Returns a handle for accessing [SpectatorV4](crate::endpoints::SpectatorV4) endpoints.
|
||||||
|
@ -101,7 +102,7 @@ impl RiotApi {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn spectator_v4(&self) -> SpectatorV4 {
|
pub fn spectator_v4(&self) -> SpectatorV4<C> {
|
||||||
SpectatorV4 { base: self }
|
SpectatorV4 { base: self }
|
||||||
}
|
}
|
||||||
/// Returns a handle for accessing [SummonerV4](crate::endpoints::SummonerV4) endpoints.
|
/// Returns a handle for accessing [SummonerV4](crate::endpoints::SummonerV4) endpoints.
|
||||||
|
@ -110,7 +111,7 @@ impl RiotApi {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn summoner_v4(&self) -> SummonerV4 {
|
pub fn summoner_v4(&self) -> SummonerV4<C> {
|
||||||
SummonerV4 { base: self }
|
SummonerV4 { base: self }
|
||||||
}
|
}
|
||||||
/// Returns a handle for accessing [TftLeagueV1](crate::endpoints::TftLeagueV1) endpoints.
|
/// Returns a handle for accessing [TftLeagueV1](crate::endpoints::TftLeagueV1) endpoints.
|
||||||
|
@ -119,7 +120,7 @@ impl RiotApi {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tft_league_v1(&self) -> TftLeagueV1 {
|
pub fn tft_league_v1(&self) -> TftLeagueV1<C> {
|
||||||
TftLeagueV1 { base: self }
|
TftLeagueV1 { base: self }
|
||||||
}
|
}
|
||||||
/// Returns a handle for accessing [TftMatchV1](crate::endpoints::TftMatchV1) endpoints.
|
/// Returns a handle for accessing [TftMatchV1](crate::endpoints::TftMatchV1) endpoints.
|
||||||
|
@ -128,7 +129,7 @@ impl RiotApi {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tft_match_v1(&self) -> TftMatchV1 {
|
pub fn tft_match_v1(&self) -> TftMatchV1<C> {
|
||||||
TftMatchV1 { base: self }
|
TftMatchV1 { base: self }
|
||||||
}
|
}
|
||||||
/// Returns a handle for accessing [TftSummonerV1](crate::endpoints::TftSummonerV1) endpoints.
|
/// Returns a handle for accessing [TftSummonerV1](crate::endpoints::TftSummonerV1) endpoints.
|
||||||
|
@ -137,7 +138,7 @@ impl RiotApi {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tft_summoner_v1(&self) -> TftSummonerV1 {
|
pub fn tft_summoner_v1(&self) -> TftSummonerV1<C> {
|
||||||
TftSummonerV1 { base: self }
|
TftSummonerV1 { base: self }
|
||||||
}
|
}
|
||||||
/// Returns a handle for accessing [ThirdPartyCodeV4](crate::endpoints::ThirdPartyCodeV4) endpoints.
|
/// Returns a handle for accessing [ThirdPartyCodeV4](crate::endpoints::ThirdPartyCodeV4) endpoints.
|
||||||
|
@ -146,7 +147,7 @@ impl RiotApi {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn third_party_code_v4(&self) -> ThirdPartyCodeV4 {
|
pub fn third_party_code_v4(&self) -> ThirdPartyCodeV4<C> {
|
||||||
ThirdPartyCodeV4 { base: self }
|
ThirdPartyCodeV4 { base: self }
|
||||||
}
|
}
|
||||||
/// Returns a handle for accessing [TournamentStubV4](crate::endpoints::TournamentStubV4) endpoints.
|
/// Returns a handle for accessing [TournamentStubV4](crate::endpoints::TournamentStubV4) endpoints.
|
||||||
|
@ -155,7 +156,7 @@ impl RiotApi {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tournament_stub_v4(&self) -> TournamentStubV4 {
|
pub fn tournament_stub_v4(&self) -> TournamentStubV4<C> {
|
||||||
TournamentStubV4 { base: self }
|
TournamentStubV4 { base: self }
|
||||||
}
|
}
|
||||||
/// Returns a handle for accessing [TournamentV4](crate::endpoints::TournamentV4) endpoints.
|
/// Returns a handle for accessing [TournamentV4](crate::endpoints::TournamentV4) endpoints.
|
||||||
|
@ -164,7 +165,7 @@ impl RiotApi {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tournament_v4(&self) -> TournamentV4 {
|
pub fn tournament_v4(&self) -> TournamentV4<C> {
|
||||||
TournamentV4 { base: self }
|
TournamentV4 { base: self }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,10 +175,10 @@ impl RiotApi {
|
||||||
/// <a href="https://developer.riotgames.com/apis#champion-mastery-v4" target="_blank">`champion-mastery-v4`</a>
|
/// <a href="https://developer.riotgames.com/apis#champion-mastery-v4" target="_blank">`champion-mastery-v4`</a>
|
||||||
///
|
///
|
||||||
/// Note: this struct is automatically generated.
|
/// Note: this struct is automatically generated.
|
||||||
pub struct ChampionMasteryV4<'a> {
|
pub struct ChampionMasteryV4<'a, C: Client> {
|
||||||
base: &'a RiotApi,
|
base: &'a RiotApi<C>,
|
||||||
}
|
}
|
||||||
impl<'a> ChampionMasteryV4<'a> {
|
impl<'a, C: Client> ChampionMasteryV4<'a, C> {
|
||||||
/// Get all champion mastery entries sorted by number of champion points descending,
|
/// Get all champion mastery entries sorted by number of champion points descending,
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `region` - Region to query.
|
/// * `region` - Region to query.
|
||||||
|
@ -231,10 +232,10 @@ impl<'a> ChampionMasteryV4<'a> {
|
||||||
/// <a href="https://developer.riotgames.com/apis#champion-v3" target="_blank">`champion-v3`</a>
|
/// <a href="https://developer.riotgames.com/apis#champion-v3" target="_blank">`champion-v3`</a>
|
||||||
///
|
///
|
||||||
/// Note: this struct is automatically generated.
|
/// Note: this struct is automatically generated.
|
||||||
pub struct ChampionV3<'a> {
|
pub struct ChampionV3<'a, C: Client> {
|
||||||
base: &'a RiotApi,
|
base: &'a RiotApi<C>,
|
||||||
}
|
}
|
||||||
impl<'a> ChampionV3<'a> {
|
impl<'a, C: Client> ChampionV3<'a, C> {
|
||||||
/// Returns champion rotations, including free-to-play and low-level free-to-play rotations (REST)
|
/// Returns champion rotations, including free-to-play and low-level free-to-play rotations (REST)
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `region` - Region to query.
|
/// * `region` - Region to query.
|
||||||
|
@ -256,11 +257,13 @@ impl<'a> ChampionV3<'a> {
|
||||||
/// <a href="https://developer.riotgames.com/apis#clash-v1" target="_blank">`clash-v1`</a>
|
/// <a href="https://developer.riotgames.com/apis#clash-v1" target="_blank">`clash-v1`</a>
|
||||||
///
|
///
|
||||||
/// Note: this struct is automatically generated.
|
/// Note: this struct is automatically generated.
|
||||||
pub struct ClashV1<'a> {
|
pub struct ClashV1<'a, C: Client> {
|
||||||
base: &'a RiotApi,
|
base: &'a RiotApi<C>,
|
||||||
}
|
}
|
||||||
impl<'a> ClashV1<'a> {
|
impl<'a, C: Client> ClashV1<'a, C> {
|
||||||
/// Get players by summoner ID.
|
/// Get players by summoner ID.
|
||||||
|
/// ## Implementation Notes
|
||||||
|
/// This endpoint returns a list of active Clash players for a given summoner ID. If a summoner registers for multiple tournaments at the same time (e.g., Saturday and Sunday) then both registrations would appear in this list.
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `region` - Region to query.
|
/// * `region` - Region to query.
|
||||||
/// * `summonerId`
|
/// * `summonerId`
|
||||||
|
@ -341,10 +344,10 @@ impl<'a> ClashV1<'a> {
|
||||||
/// <a href="https://developer.riotgames.com/apis#league-exp-v4" target="_blank">`league-exp-v4`</a>
|
/// <a href="https://developer.riotgames.com/apis#league-exp-v4" target="_blank">`league-exp-v4`</a>
|
||||||
///
|
///
|
||||||
/// Note: this struct is automatically generated.
|
/// Note: this struct is automatically generated.
|
||||||
pub struct LeagueExpV4<'a> {
|
pub struct LeagueExpV4<'a, C: Client> {
|
||||||
base: &'a RiotApi,
|
base: &'a RiotApi<C>,
|
||||||
}
|
}
|
||||||
impl<'a> LeagueExpV4<'a> {
|
impl<'a, C: Client> LeagueExpV4<'a, C> {
|
||||||
/// Get all the league entries.
|
/// Get all the league entries.
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `region` - Region to query.
|
/// * `region` - Region to query.
|
||||||
|
@ -373,10 +376,10 @@ impl<'a> LeagueExpV4<'a> {
|
||||||
/// <a href="https://developer.riotgames.com/apis#league-v4" target="_blank">`league-v4`</a>
|
/// <a href="https://developer.riotgames.com/apis#league-v4" target="_blank">`league-v4`</a>
|
||||||
///
|
///
|
||||||
/// Note: this struct is automatically generated.
|
/// Note: this struct is automatically generated.
|
||||||
pub struct LeagueV4<'a> {
|
pub struct LeagueV4<'a, C: Client> {
|
||||||
base: &'a RiotApi,
|
base: &'a RiotApi<C>,
|
||||||
}
|
}
|
||||||
impl<'a> LeagueV4<'a> {
|
impl<'a, C: Client> LeagueV4<'a, C> {
|
||||||
/// Get the challenger league for given queue.
|
/// Get the challenger league for given queue.
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `region` - Region to query.
|
/// * `region` - Region to query.
|
||||||
|
@ -480,10 +483,10 @@ impl<'a> LeagueV4<'a> {
|
||||||
/// <a href="https://developer.riotgames.com/apis#lol-status-v3" target="_blank">`lol-status-v3`</a>
|
/// <a href="https://developer.riotgames.com/apis#lol-status-v3" target="_blank">`lol-status-v3`</a>
|
||||||
///
|
///
|
||||||
/// Note: this struct is automatically generated.
|
/// Note: this struct is automatically generated.
|
||||||
pub struct LolStatusV3<'a> {
|
pub struct LolStatusV3<'a, C: Client> {
|
||||||
base: &'a RiotApi,
|
base: &'a RiotApi<C>,
|
||||||
}
|
}
|
||||||
impl<'a> LolStatusV3<'a> {
|
impl<'a, C: Client> LolStatusV3<'a, C> {
|
||||||
/// Get League of Legends status for the given shard.
|
/// Get League of Legends status for the given shard.
|
||||||
/// ## Rate Limit Notes
|
/// ## Rate Limit Notes
|
||||||
/// Requests to this API are not counted against the application Rate Limits.
|
/// Requests to this API are not counted against the application Rate Limits.
|
||||||
|
@ -507,10 +510,10 @@ impl<'a> LolStatusV3<'a> {
|
||||||
/// <a href="https://developer.riotgames.com/apis#lor-ranked-v1" target="_blank">`lor-ranked-v1`</a>
|
/// <a href="https://developer.riotgames.com/apis#lor-ranked-v1" target="_blank">`lor-ranked-v1`</a>
|
||||||
///
|
///
|
||||||
/// Note: this struct is automatically generated.
|
/// Note: this struct is automatically generated.
|
||||||
pub struct LorRankedV1<'a> {
|
pub struct LorRankedV1<'a, C: Client> {
|
||||||
base: &'a RiotApi,
|
base: &'a RiotApi<C>,
|
||||||
}
|
}
|
||||||
impl<'a> LorRankedV1<'a> {
|
impl<'a, C: Client> LorRankedV1<'a, C> {
|
||||||
/// Get the players in Master tier.
|
/// Get the players in Master tier.
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `region` - Region to query.
|
/// * `region` - Region to query.
|
||||||
|
@ -532,10 +535,10 @@ impl<'a> LorRankedV1<'a> {
|
||||||
/// <a href="https://developer.riotgames.com/apis#match-v4" target="_blank">`match-v4`</a>
|
/// <a href="https://developer.riotgames.com/apis#match-v4" target="_blank">`match-v4`</a>
|
||||||
///
|
///
|
||||||
/// Note: this struct is automatically generated.
|
/// Note: this struct is automatically generated.
|
||||||
pub struct MatchV4<'a> {
|
pub struct MatchV4<'a, C: Client> {
|
||||||
base: &'a RiotApi,
|
base: &'a RiotApi<C>,
|
||||||
}
|
}
|
||||||
impl<'a> MatchV4<'a> {
|
impl<'a, C: Client> MatchV4<'a, C> {
|
||||||
/// Get match IDs by tournament code.
|
/// Get match IDs by tournament code.
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `region` - Region to query.
|
/// * `region` - Region to query.
|
||||||
|
@ -643,10 +646,10 @@ impl<'a> MatchV4<'a> {
|
||||||
/// <a href="https://developer.riotgames.com/apis#spectator-v4" target="_blank">`spectator-v4`</a>
|
/// <a href="https://developer.riotgames.com/apis#spectator-v4" target="_blank">`spectator-v4`</a>
|
||||||
///
|
///
|
||||||
/// Note: this struct is automatically generated.
|
/// Note: this struct is automatically generated.
|
||||||
pub struct SpectatorV4<'a> {
|
pub struct SpectatorV4<'a, C: Client> {
|
||||||
base: &'a RiotApi,
|
base: &'a RiotApi<C>,
|
||||||
}
|
}
|
||||||
impl<'a> SpectatorV4<'a> {
|
impl<'a, C: Client> SpectatorV4<'a, C> {
|
||||||
/// Get current game information for the given summoner ID.
|
/// Get current game information for the given summoner ID.
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `region` - Region to query.
|
/// * `region` - Region to query.
|
||||||
|
@ -683,10 +686,10 @@ impl<'a> SpectatorV4<'a> {
|
||||||
/// <a href="https://developer.riotgames.com/apis#summoner-v4" target="_blank">`summoner-v4`</a>
|
/// <a href="https://developer.riotgames.com/apis#summoner-v4" target="_blank">`summoner-v4`</a>
|
||||||
///
|
///
|
||||||
/// Note: this struct is automatically generated.
|
/// Note: this struct is automatically generated.
|
||||||
pub struct SummonerV4<'a> {
|
pub struct SummonerV4<'a, C: Client> {
|
||||||
base: &'a RiotApi,
|
base: &'a RiotApi<C>,
|
||||||
}
|
}
|
||||||
impl<'a> SummonerV4<'a> {
|
impl<'a, C: Client> SummonerV4<'a, C> {
|
||||||
/// Get a summoner by account ID.
|
/// Get a summoner by account ID.
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `region` - Region to query.
|
/// * `region` - Region to query.
|
||||||
|
@ -754,10 +757,10 @@ impl<'a> SummonerV4<'a> {
|
||||||
/// <a href="https://developer.riotgames.com/apis#tft-league-v1" target="_blank">`tft-league-v1`</a>
|
/// <a href="https://developer.riotgames.com/apis#tft-league-v1" target="_blank">`tft-league-v1`</a>
|
||||||
///
|
///
|
||||||
/// Note: this struct is automatically generated.
|
/// Note: this struct is automatically generated.
|
||||||
pub struct TftLeagueV1<'a> {
|
pub struct TftLeagueV1<'a, C: Client> {
|
||||||
base: &'a RiotApi,
|
base: &'a RiotApi<C>,
|
||||||
}
|
}
|
||||||
impl<'a> TftLeagueV1<'a> {
|
impl<'a, C: Client> TftLeagueV1<'a, C> {
|
||||||
/// Get the challenger league.
|
/// Get the challenger league.
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `region` - Region to query.
|
/// * `region` - Region to query.
|
||||||
|
@ -857,10 +860,10 @@ impl<'a> TftLeagueV1<'a> {
|
||||||
/// <a href="https://developer.riotgames.com/apis#tft-match-v1" target="_blank">`tft-match-v1`</a>
|
/// <a href="https://developer.riotgames.com/apis#tft-match-v1" target="_blank">`tft-match-v1`</a>
|
||||||
///
|
///
|
||||||
/// Note: this struct is automatically generated.
|
/// Note: this struct is automatically generated.
|
||||||
pub struct TftMatchV1<'a> {
|
pub struct TftMatchV1<'a, C: Client> {
|
||||||
base: &'a RiotApi,
|
base: &'a RiotApi<C>,
|
||||||
}
|
}
|
||||||
impl<'a> TftMatchV1<'a> {
|
impl<'a, C: Client> TftMatchV1<'a, C> {
|
||||||
/// Get a list of match ids by PUUID.
|
/// Get a list of match ids by PUUID.
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `region` - Region to query.
|
/// * `region` - Region to query.
|
||||||
|
@ -902,10 +905,10 @@ impl<'a> TftMatchV1<'a> {
|
||||||
/// <a href="https://developer.riotgames.com/apis#tft-summoner-v1" target="_blank">`tft-summoner-v1`</a>
|
/// <a href="https://developer.riotgames.com/apis#tft-summoner-v1" target="_blank">`tft-summoner-v1`</a>
|
||||||
///
|
///
|
||||||
/// Note: this struct is automatically generated.
|
/// Note: this struct is automatically generated.
|
||||||
pub struct TftSummonerV1<'a> {
|
pub struct TftSummonerV1<'a, C: Client> {
|
||||||
base: &'a RiotApi,
|
base: &'a RiotApi<C>,
|
||||||
}
|
}
|
||||||
impl<'a> TftSummonerV1<'a> {
|
impl<'a, C: Client> TftSummonerV1<'a, C> {
|
||||||
/// Get a summoner by account ID.
|
/// Get a summoner by account ID.
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `region` - Region to query.
|
/// * `region` - Region to query.
|
||||||
|
@ -973,10 +976,10 @@ impl<'a> TftSummonerV1<'a> {
|
||||||
/// <a href="https://developer.riotgames.com/apis#third-party-code-v4" target="_blank">`third-party-code-v4`</a>
|
/// <a href="https://developer.riotgames.com/apis#third-party-code-v4" target="_blank">`third-party-code-v4`</a>
|
||||||
///
|
///
|
||||||
/// Note: this struct is automatically generated.
|
/// Note: this struct is automatically generated.
|
||||||
pub struct ThirdPartyCodeV4<'a> {
|
pub struct ThirdPartyCodeV4<'a, C: Client> {
|
||||||
base: &'a RiotApi,
|
base: &'a RiotApi<C>,
|
||||||
}
|
}
|
||||||
impl<'a> ThirdPartyCodeV4<'a> {
|
impl<'a, C: Client> ThirdPartyCodeV4<'a, C> {
|
||||||
/// Get third party code for a given summoner ID.
|
/// Get third party code for a given summoner ID.
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `region` - Region to query.
|
/// * `region` - Region to query.
|
||||||
|
@ -999,10 +1002,10 @@ impl<'a> ThirdPartyCodeV4<'a> {
|
||||||
/// <a href="https://developer.riotgames.com/apis#tournament-stub-v4" target="_blank">`tournament-stub-v4`</a>
|
/// <a href="https://developer.riotgames.com/apis#tournament-stub-v4" target="_blank">`tournament-stub-v4`</a>
|
||||||
///
|
///
|
||||||
/// Note: this struct is automatically generated.
|
/// Note: this struct is automatically generated.
|
||||||
pub struct TournamentStubV4<'a> {
|
pub struct TournamentStubV4<'a, C: Client> {
|
||||||
base: &'a RiotApi,
|
base: &'a RiotApi<C>,
|
||||||
}
|
}
|
||||||
impl<'a> TournamentStubV4<'a> {
|
impl<'a, C: Client> TournamentStubV4<'a, C> {
|
||||||
/// Gets a mock list of lobby events by tournament code.
|
/// Gets a mock list of lobby events by tournament code.
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `region` - Region to query.
|
/// * `region` - Region to query.
|
||||||
|
@ -1025,10 +1028,10 @@ impl<'a> TournamentStubV4<'a> {
|
||||||
/// <a href="https://developer.riotgames.com/apis#tournament-v4" target="_blank">`tournament-v4`</a>
|
/// <a href="https://developer.riotgames.com/apis#tournament-v4" target="_blank">`tournament-v4`</a>
|
||||||
///
|
///
|
||||||
/// Note: this struct is automatically generated.
|
/// Note: this struct is automatically generated.
|
||||||
pub struct TournamentV4<'a> {
|
pub struct TournamentV4<'a, C: Client> {
|
||||||
base: &'a RiotApi,
|
base: &'a RiotApi<C>,
|
||||||
}
|
}
|
||||||
impl<'a> TournamentV4<'a> {
|
impl<'a, C: Client> TournamentV4<'a, C> {
|
||||||
/// Returns the tournament code DTO associated with a tournament code string.
|
/// Returns the tournament code DTO associated with a tournament code string.
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `region` - Region to query.
|
/// * `region` - Region to query.
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
/// Re-exported `reqwest` types.
|
use crate::reqwest::*;
|
||||||
pub mod reqwest {
|
|
||||||
pub use reqwest::{
|
|
||||||
Error, Response, StatusCode, Url
|
|
||||||
};
|
|
||||||
}
|
|
||||||
use ::reqwest::*;
|
|
||||||
|
|
||||||
/// Result containing RiotApiError on failure.
|
/// Result containing RiotApiError on failure.
|
||||||
pub type Result<T> = std::result::Result<T, RiotApiError>;
|
pub type Result<T> = std::result::Result<T, RiotApiError>;
|
||||||
|
|
|
@ -6,6 +6,11 @@
|
||||||
#![cfg_attr(feature = "nightly", doc(include = "../README.md"))]
|
#![cfg_attr(feature = "nightly", doc(include = "../README.md"))]
|
||||||
#![cfg_attr(not(feature = "nightly"), doc = "See [README.md](https://github.com/MingweiSamuel/Riven#readme).")]
|
#![cfg_attr(not(feature = "nightly"), doc = "See [README.md](https://github.com/MingweiSamuel/Riven#readme).")]
|
||||||
|
|
||||||
|
/// Re-exported `reqwest` types.
|
||||||
|
pub use reqwest;
|
||||||
|
|
||||||
|
pub mod client;
|
||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
pub use config::RiotApiConfig;
|
pub use config::RiotApiConfig;
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
||||||
// Version 71bb788ab92c0b03d5dd284402d9514b625fe2a4
|
// Version 64f3c82d132f12808d8eb8f483d1d2182386c432
|
||||||
|
|
||||||
//! Data transfer structs.
|
//! Data transfer structs.
|
||||||
//!
|
//!
|
||||||
|
@ -466,7 +466,7 @@ pub mod match_v4 {
|
||||||
pub struct ParticipantIdentity {
|
pub struct ParticipantIdentity {
|
||||||
#[serde(rename = "participantId")]
|
#[serde(rename = "participantId")]
|
||||||
pub participant_id: i32,
|
pub participant_id: i32,
|
||||||
/// Player information.
|
/// Player information not included in the response for custom matches. Custom matches are considered private unless a tournament code was used to create the match.
|
||||||
#[serde(rename = "player")]
|
#[serde(rename = "player")]
|
||||||
pub player: Player,
|
pub player: Player,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//! Module containing rate limiting and requesting types.
|
//! Contains rate limiting and requesting types.
|
||||||
|
|
||||||
mod rate_limit;
|
mod rate_limit;
|
||||||
pub use rate_limit::*;
|
pub use rate_limit::*;
|
||||||
|
|
|
@ -3,10 +3,10 @@ use std::time::{ Duration, Instant };
|
||||||
|
|
||||||
use log;
|
use log;
|
||||||
use parking_lot::{ RwLock, RwLockUpgradableReadGuard };
|
use parking_lot::{ RwLock, RwLockUpgradableReadGuard };
|
||||||
use reqwest::{ StatusCode, Response };
|
|
||||||
use scan_fmt::scan_fmt;
|
use scan_fmt::scan_fmt;
|
||||||
|
|
||||||
use crate::RiotApiConfig;
|
use crate::RiotApiConfig;
|
||||||
|
use crate::client::Response;
|
||||||
use super::{ TokenBucket, VectorTokenBucket };
|
use super::{ TokenBucket, VectorTokenBucket };
|
||||||
use super::RateLimitType;
|
use super::RateLimitType;
|
||||||
|
|
||||||
|
@ -68,25 +68,25 @@ impl RateLimit {
|
||||||
self.retry_after.read().and_then(|i| Instant::now().checked_duration_since(i))
|
self.retry_after.read().and_then(|i| Instant::now().checked_duration_since(i))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_response(&self, config: &RiotApiConfig, response: &Response) {
|
pub fn on_response<R: Response>(&self, config: &RiotApiConfig, response: &R) {
|
||||||
self.on_response_retry_after(response);
|
self.on_response_retry_after(response);
|
||||||
self.on_response_rate_limits(config, response);
|
self.on_response_rate_limits(config, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `on_response` helper for retry after check.
|
/// `on_response` helper for retry after check.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn on_response_retry_after(&self, response: &Response) {
|
fn on_response_retry_after<R: Response>(&self, response: &R) {
|
||||||
if let Some(retry_after) = || -> Option<Instant> {
|
if let Some(retry_after) = || -> Option<Instant> {
|
||||||
// Only care about 429s.
|
// Only care about 429 Too Many Requests.
|
||||||
if StatusCode::TOO_MANY_REQUESTS != response.status() {
|
if 429 != response.status() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Only care if the header that indicates the relevant RateLimit is present.
|
// Only care if the header that indicates the relevant RateLimit is present.
|
||||||
let type_name_header = response.headers()
|
let type_name_header = response
|
||||||
.get(RateLimit::HEADER_XRATELIMITTYPE)?.to_str()
|
.header(RateLimit::HEADER_XRATELIMITTYPE)?;
|
||||||
.expect("Failed to read x-rate-limit-type header as string.");
|
// .expect("Failed to read x-rate-limit-type header as string.");
|
||||||
// Only care if that header's value matches us.
|
// Only care if that header's value matches us.
|
||||||
if self.rate_limit_type.type_name() != type_name_header.to_lowercase() {
|
if self.rate_limit_type.type_name() != type_name_header.to_lowercase() {
|
||||||
return None;
|
return None;
|
||||||
|
@ -94,9 +94,9 @@ impl RateLimit {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get retry after header. Only care if it exists.
|
// Get retry after header. Only care if it exists.
|
||||||
let retry_after_header = response.headers()
|
let retry_after_header = response
|
||||||
.get(RateLimit::HEADER_RETRYAFTER)?.to_str()
|
.header(RateLimit::HEADER_RETRYAFTER)?;
|
||||||
.expect("Failed to read retry-after header as string.");
|
// .expect("Failed to read retry-after header as string.");
|
||||||
|
|
||||||
log::debug!("Hit 429, retry-after {} secs.", retry_after_header);
|
log::debug!("Hit 429, retry-after {} secs.", retry_after_header);
|
||||||
|
|
||||||
|
@ -112,26 +112,26 @@ impl RateLimit {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn on_response_rate_limits(&self, config: &RiotApiConfig, response: &Response) {
|
fn on_response_rate_limits<R: Response>(&self, config: &RiotApiConfig, response: &R) {
|
||||||
// Check if rate limits changed.
|
// Check if rate limits changed.
|
||||||
let headers = response.headers();
|
// let headers = response.headers();
|
||||||
let limit_header_opt = headers.get(self.rate_limit_type.limit_header())
|
let limit_header_opt = response.header(self.rate_limit_type.limit_header());
|
||||||
.map(|h| h.to_str().expect("Failed to read limit header as string."));
|
// .map(|h| h.to_str().expect("Failed to read limit header as string."));
|
||||||
let count_header_opt = headers.get(self.rate_limit_type.count_header())
|
let count_header_opt = response.header(self.rate_limit_type.count_header());
|
||||||
.map(|h| h.to_str().expect("Failed to read count header as string."));
|
// .map(|h| h.to_str().expect("Failed to read count header as string."));
|
||||||
|
|
||||||
// https://github.com/rust-lang/rust/issues/53667
|
// https://github.com/rust-lang/rust/issues/53667
|
||||||
if let Some(limit_header) = limit_header_opt {
|
if let Some(limit_header) = limit_header_opt {
|
||||||
if let Some(count_header) = count_header_opt {
|
if let Some(count_header) = count_header_opt {
|
||||||
|
|
||||||
let buckets = self.buckets.upgradable_read();
|
let buckets = self.buckets.upgradable_read();
|
||||||
if !buckets_require_updating(limit_header, &*buckets) {
|
if !buckets_require_updating(&limit_header, &*buckets) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buckets require updating. Upgrade to write lock.
|
// Buckets require updating. Upgrade to write lock.
|
||||||
let mut buckets = RwLockUpgradableReadGuard::upgrade(buckets);
|
let mut buckets = RwLockUpgradableReadGuard::upgrade(buckets);
|
||||||
*buckets = buckets_from_header(config, limit_header, count_header)
|
*buckets = buckets_from_header(config, &limit_header, &count_header)
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@ use std::future::Future;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use log;
|
use log;
|
||||||
use reqwest::{ Client, StatusCode, Url };
|
|
||||||
use tokio::time::delay_for;
|
use tokio::time::delay_for;
|
||||||
|
|
||||||
|
use crate::client::{ Client, Response };
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use crate::RiotApiError;
|
use crate::RiotApiError;
|
||||||
use crate::RiotApiConfig;
|
use crate::RiotApiConfig;
|
||||||
|
@ -25,9 +25,9 @@ impl RegionalRequester {
|
||||||
const RIOT_KEY_HEADER: &'static str = "X-Riot-Token";
|
const RIOT_KEY_HEADER: &'static str = "X-Riot-Token";
|
||||||
|
|
||||||
/// HTTP status codes which are considered a success but will results in `None`.
|
/// HTTP status codes which are considered a success but will results in `None`.
|
||||||
const NONE_STATUS_CODES: [StatusCode; 2] = [
|
const NONE_STATUS_CODES: [u16; 2] = [
|
||||||
StatusCode::NO_CONTENT, // 204
|
204, // No Content.
|
||||||
StatusCode::NOT_FOUND, // 404
|
404, // Not Found.
|
||||||
];
|
];
|
||||||
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
@ -37,27 +37,28 @@ impl RegionalRequester {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_optional<'a, T: serde::de::DeserializeOwned>(self: Arc<Self>,
|
pub fn get_optional<'a, C: Client, T: serde::de::DeserializeOwned + 'static>(self: Arc<Self>,
|
||||||
config: &'a RiotApiConfig, client: &'a Client,
|
config: &'a RiotApiConfig, client: &'a C,
|
||||||
method_id: &'static str, region_platform: &'a str, path: String, query: Option<String>)
|
method_id: &'static str, region_platform: &'a str, path: String, query: Option<String>)
|
||||||
-> impl Future<Output = Result<Option<T>>> + 'a
|
-> impl Future<Output = Result<Option<T>>> + 'a
|
||||||
{
|
{
|
||||||
async move {
|
async move {
|
||||||
let response_result = self.get(config, client,
|
panic!("FIXME");
|
||||||
method_id, region_platform, path, query).await;
|
// let response_result = self.get(config, client,
|
||||||
response_result.map(|value| Some(value))
|
// method_id, region_platform, path, query).await;
|
||||||
.or_else(|e| {
|
// response_result.map(|value| Some(value))
|
||||||
if let Some(status) = e.status_code() {
|
// .or_else(|e| {
|
||||||
if Self::NONE_STATUS_CODES.contains(&status) {
|
// if let Some(status) = e.status_code() {
|
||||||
return Ok(None);
|
// if Self::NONE_STATUS_CODES.contains(&status) {
|
||||||
}}
|
// return Ok(None);
|
||||||
Err(e)
|
// }}
|
||||||
})
|
// Err(e)
|
||||||
|
// })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get<'a, T: serde::de::DeserializeOwned>(self: Arc<Self>,
|
pub fn get<'a, C: Client, T: serde::de::DeserializeOwned + 'static>(self: Arc<Self>,
|
||||||
config: &'a RiotApiConfig, client: &'a Client,
|
config: &'a RiotApiConfig, client: &'a C,
|
||||||
method_id: &'static str, region_platform: &'a str, path: String, query: Option<String>)
|
method_id: &'static str, region_platform: &'a str, path: String, query: Option<String>)
|
||||||
-> impl Future<Output = Result<T>> + 'a
|
-> impl Future<Output = Result<T>> + 'a
|
||||||
{
|
{
|
||||||
|
@ -77,16 +78,10 @@ impl RegionalRequester {
|
||||||
|
|
||||||
// Send request.
|
// Send request.
|
||||||
let url_base = format!("https://{}.api.riotgames.com", region_platform);
|
let url_base = format!("https://{}.api.riotgames.com", region_platform);
|
||||||
let mut url = Url::parse(&*url_base)
|
let response = client.get(url_base, &path, query, vec![( Self::RIOT_KEY_HEADER, &config.api_key )])
|
||||||
.unwrap_or_else(|_| panic!("Failed to parse url_base: \"{}\".", url_base));
|
|
||||||
url.set_path(&*path);
|
|
||||||
url.set_query(query);
|
|
||||||
|
|
||||||
let response = client.get(url)
|
|
||||||
.header(Self::RIOT_KEY_HEADER, &*config.api_key)
|
|
||||||
.send()
|
|
||||||
.await
|
.await
|
||||||
.map_err(|e| RiotApiError::new(e, retries, None, None))?;
|
.unwrap(); // FIXME
|
||||||
|
// .map_err(|e| RiotApiError::new(e, retries, None, None))?;
|
||||||
|
|
||||||
// Maybe update rate limits (based on response headers).
|
// Maybe update rate limits (based on response headers).
|
||||||
self.app_rate_limit.on_response(&config, &response);
|
self.app_rate_limit.on_response(&config, &response);
|
||||||
|
@ -94,27 +89,20 @@ impl RegionalRequester {
|
||||||
|
|
||||||
let status = response.status();
|
let status = response.status();
|
||||||
// Handle normal success / failure cases.
|
// Handle normal success / failure cases.
|
||||||
match response.error_for_status_ref() {
|
if 200 == status {
|
||||||
// Success.
|
// Success.
|
||||||
Ok(_response) => {
|
|
||||||
log::trace!("Response {} (retried {} times), parsed result.", status, retries);
|
log::trace!("Response {} (retried {} times), parsed result.", status, retries);
|
||||||
let value = response.json::<T>().await;
|
let value = response.into_json::<T>().await;
|
||||||
break value.map_err(|e| RiotApiError::new(e, retries, None, Some(status)));
|
break value.map_err(|e| panic!("FIXME")); //RiotApiError::new(Some(e), retries, None, Some(status)));
|
||||||
},
|
}
|
||||||
// Failure, may or may not be retryable.
|
|
||||||
Err(err) => {
|
|
||||||
// Not-retryable: no more retries or 4xx or ? (3xx, redirects exceeded).
|
// Not-retryable: no more retries or 4xx or ? (3xx, redirects exceeded).
|
||||||
// Retryable: retries remaining, and 429 or 5xx.
|
// Retryable: retries remaining, and 429 or 5xx.
|
||||||
if retries >= config.retries ||
|
if retries >= config.retries || (429 != status && 500 > status)
|
||||||
(StatusCode::TOO_MANY_REQUESTS != status
|
|
||||||
&& !status.is_server_error())
|
|
||||||
{
|
{
|
||||||
log::debug!("Response {} (retried {} times), returning.", status, retries);
|
log::debug!("Response {} (retried {} times), returning.", status, retries);
|
||||||
break Err(RiotApiError::new(err, retries, Some(response), Some(status)));
|
panic!("FIXME"); // FIXME break Err(RiotApiError::new(None, retries, Some(response), Some(status)));
|
||||||
}
|
}
|
||||||
log::debug!("Response {} (retried {} times), retrying.", status, retries);
|
log::debug!("Response {} (retried {} times), retrying.", status, retries);
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
retries += 1;
|
retries += 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@ use std::future::Future;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use log;
|
use log;
|
||||||
use reqwest::Client;
|
|
||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
use crate::client::Client;
|
||||||
use crate::RiotApiConfig;
|
use crate::RiotApiConfig;
|
||||||
use crate::req::RegionalRequester;
|
use crate::req::RegionalRequester;
|
||||||
use crate::util::InsertOnlyCHashMap;
|
use crate::util::InsertOnlyCHashMap;
|
||||||
|
@ -34,24 +34,30 @@ use crate::util::InsertOnlyCHashMap;
|
||||||
///
|
///
|
||||||
/// To adjust rate limiting, see [RiotApiConfig](crate::RiotApiConfig) and use
|
/// To adjust rate limiting, see [RiotApiConfig](crate::RiotApiConfig) and use
|
||||||
/// [`with_config(config)`](RiotApi::with_config) to construct an instance.
|
/// [`with_config(config)`](RiotApi::with_config) to construct an instance.
|
||||||
pub struct RiotApi {
|
pub struct RiotApi<C: Client> {
|
||||||
/// Configuration settings.
|
/// Configuration settings.
|
||||||
config: RiotApiConfig,
|
config: RiotApiConfig,
|
||||||
/// Client for making requests.
|
/// Client for making requests.
|
||||||
client: Client,
|
client: C,
|
||||||
|
|
||||||
/// Per-region requesters.
|
/// Per-region requesters.
|
||||||
regional_requesters: InsertOnlyCHashMap<&'static str, RegionalRequester>,
|
regional_requesters: InsertOnlyCHashMap<&'static str, RegionalRequester>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RiotApi {
|
impl<C: Client> RiotApi<C> {
|
||||||
/// Constructs a new instance from the given [RiotApiConfig](crate::RiotApiConfig), consuming it.
|
/// Constructs a new instance from the given [RiotApiConfig](crate::RiotApiConfig), consuming it.
|
||||||
pub fn with_config(mut config: RiotApiConfig) -> Self {
|
pub fn with_config(mut config: RiotApiConfig) -> Self {
|
||||||
let client_builder = config.client_builder.take()
|
//FIXME
|
||||||
.expect("!NONE CLIENT_BUILDER IN CONFIG.");
|
// let client_builder = config.client_builder.take()
|
||||||
|
// .expect("!NONE CLIENT_BUILDER IN CONFIG.");
|
||||||
|
// Self {
|
||||||
|
// config: config,
|
||||||
|
// client: client_builder.build().expect("Failed to create client from builder."),
|
||||||
|
// regional_requesters: InsertOnlyCHashMap::new(),
|
||||||
|
// }
|
||||||
Self {
|
Self {
|
||||||
config: config,
|
config: config,
|
||||||
client: client_builder.build().expect("Failed to create client from builder."),
|
client: C::new(),
|
||||||
regional_requesters: InsertOnlyCHashMap::new(),
|
regional_requesters: InsertOnlyCHashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +80,7 @@ impl RiotApi {
|
||||||
/// * `region_platform` - The stringified platform, prepended to `.api.riotgames.com` to create the hostname.
|
/// * `region_platform` - The stringified platform, prepended to `.api.riotgames.com` to create the hostname.
|
||||||
/// * `path` - The path relative to the hostname.
|
/// * `path` - The path relative to the hostname.
|
||||||
/// * `query` - An optional query string.
|
/// * `query` - An optional query string.
|
||||||
pub fn get_optional<'a, T: serde::de::DeserializeOwned + 'a>(&'a self,
|
pub fn get_optional<'a, T: serde::de::DeserializeOwned + 'static>(&'a self,
|
||||||
method_id: &'static str, region_platform: &'static str, path: String, query: Option<String>)
|
method_id: &'static str, region_platform: &'static str, path: String, query: Option<String>)
|
||||||
-> impl Future<Output = Result<Option<T>>> + 'a
|
-> impl Future<Output = Result<Option<T>>> + 'a
|
||||||
{
|
{
|
||||||
|
@ -91,7 +97,7 @@ impl RiotApi {
|
||||||
/// * `region_platform` - The stringified platform, prepended to `.api.riotgames.com` to create the hostname.
|
/// * `region_platform` - The stringified platform, prepended to `.api.riotgames.com` to create the hostname.
|
||||||
/// * `path` - The path relative to the hostname.
|
/// * `path` - The path relative to the hostname.
|
||||||
/// * `query` - An optional query string.
|
/// * `query` - An optional query string.
|
||||||
pub fn get<'a, T: serde::de::DeserializeOwned + 'a>(&'a self,
|
pub fn get<'a, T: serde::de::DeserializeOwned + 'static>(&'a self,
|
||||||
method_id: &'static str, region_platform: &'static str, path: String, query: Option<String>)
|
method_id: &'static str, region_platform: &'static str, path: String, query: Option<String>)
|
||||||
-> impl Future<Output = Result<T>> + 'a
|
-> impl Future<Output = Result<T>> + 'a
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,6 +16,7 @@ use std::vec::Vec;
|
||||||
use url::form_urlencoded::Serializer;
|
use url::form_urlencoded::Serializer;
|
||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
use crate::client::Client;
|
||||||
use crate::consts::Region;
|
use crate::consts::Region;
|
||||||
use crate::riot_api::RiotApi;
|
use crate::riot_api::RiotApi;
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ use crate::riot_api::RiotApi;
|
||||||
endpointGroups[ep].push(path);
|
endpointGroups[ep].push(path);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
impl RiotApi {
|
impl<C: Client> RiotApi<C> {
|
||||||
{{
|
{{
|
||||||
for (const endpointName of Object.keys(endpointGroups)) {
|
for (const endpointName of Object.keys(endpointGroups)) {
|
||||||
const method = dotUtils.changeCase.snakeCase(endpointName);
|
const method = dotUtils.changeCase.snakeCase(endpointName);
|
||||||
|
@ -39,7 +40,7 @@ impl RiotApi {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn {{= method }}(&self) -> {{= type }} {
|
pub fn {{= method }}(&self) -> {{= type }}<C> {
|
||||||
{{= type }} { base: self }
|
{{= type }} { base: self }
|
||||||
}
|
}
|
||||||
{{
|
{{
|
||||||
|
@ -57,10 +58,10 @@ impl RiotApi {
|
||||||
/// <a href="https://developer.riotgames.com/apis#{{= endpointName }}" target="_blank">`{{= endpointName }}`</a>
|
/// <a href="https://developer.riotgames.com/apis#{{= endpointName }}" target="_blank">`{{= endpointName }}`</a>
|
||||||
///
|
///
|
||||||
/// Note: this struct is automatically generated.
|
/// Note: this struct is automatically generated.
|
||||||
pub struct {{= endpoint }}<'a> {
|
pub struct {{= endpoint }}<'a, C: Client> {
|
||||||
base: &'a RiotApi,
|
base: &'a RiotApi<C>,
|
||||||
}
|
}
|
||||||
impl<'a> {{= endpoint }}<'a> {
|
impl<'a, C: Client> {{= endpoint }}<'a, C> {
|
||||||
{{
|
{{
|
||||||
for (let [ route, path ] of endpointMethods)
|
for (let [ route, path ] of endpointMethods)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue