forked from mirror/Riven
Compare commits
21 Commits
Author | SHA1 | Date |
---|---|---|
Mingwei Samuel | e50c509f17 | |
Mingwei Samuel | a55d7769d2 | |
Mingwei Samuel | efbd101e83 | |
Mingwei Samuel | 35d32eeb24 | |
Mingwei Samuel | b30342ac47 | |
Mingwei Samuel | 80eeb184a0 | |
Mingwei Samuel | f090d107b2 | |
Mingwei Samuel | d72ebba4e3 | |
Mingwei Samuel | d621daf3e1 | |
Mingwei Samuel | 40ff477614 | |
Mingwei Samuel | 3bd6812b94 | |
Mingwei Samuel | 054fa0f405 | |
Mingwei Samuel | ac880ab2e5 | |
Mingwei Samuel | 3a160a51bb | |
Mingwei Samuel | a94453a018 | |
Mingwei Samuel | 612ffde26b | |
Mingwei Samuel | 5987a6f07f | |
Mingwei Samuel | 7af67d0cd6 | |
Mingwei Samuel | 50f1a4afde | |
Mingwei Samuel | 51c0832174 | |
Mingwei Samuel | e7c9595a08 |
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "riven"
|
name = "riven"
|
||||||
version = "1.12.1"
|
version = "1.15.0"
|
||||||
authors = ["Mingwei Samuel <mingwei.samuel@gmail.com>"]
|
authors = ["Mingwei Samuel <mingwei.samuel@gmail.com>"]
|
||||||
repository = "https://github.com/MingweiSamuel/Riven"
|
repository = "https://github.com/MingweiSamuel/Riven"
|
||||||
description = "Riot Games API Library"
|
description = "Riot Games API Library"
|
||||||
|
@ -21,6 +21,8 @@ features = [ "nightly" ]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
nightly = [ "parking_lot/nightly" ]
|
nightly = [ "parking_lot/nightly" ]
|
||||||
|
native-tls = [ "reqwest/native-tls" ]
|
||||||
|
rustls-tls = [ "reqwest/rustls-tls" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
|
|
|
@ -34,6 +34,8 @@ pub enum Champion {
|
||||||
#[strum(to_string="Ahri")] Ahri = 103,
|
#[strum(to_string="Ahri")] Ahri = 103,
|
||||||
/// Akali (`Akali`, 84).
|
/// Akali (`Akali`, 84).
|
||||||
#[strum(to_string="Akali")] Akali = 84,
|
#[strum(to_string="Akali")] Akali = 84,
|
||||||
|
/// Akshan (`Akshan`, 166).
|
||||||
|
#[strum(to_string="Akshan")] Akshan = 166,
|
||||||
/// Alistar (`Alistar`, 12).
|
/// Alistar (`Alistar`, 12).
|
||||||
#[strum(to_string="Alistar")] Alistar = 12,
|
#[strum(to_string="Alistar")] Alistar = 12,
|
||||||
/// Amumu (`Amumu`, 32).
|
/// Amumu (`Amumu`, 32).
|
||||||
|
@ -298,6 +300,8 @@ pub enum Champion {
|
||||||
#[strum(to_string="Veigar")] Veigar = 45,
|
#[strum(to_string="Veigar")] Veigar = 45,
|
||||||
/// Vel'Koz (`Velkoz`, 161).
|
/// Vel'Koz (`Velkoz`, 161).
|
||||||
#[strum(to_string="Vel'Koz", serialize="Velkoz")] VelKoz = 161,
|
#[strum(to_string="Vel'Koz", serialize="Velkoz")] VelKoz = 161,
|
||||||
|
/// Vex (`Vex`, 711).
|
||||||
|
#[strum(to_string="Vex")] Vex = 711,
|
||||||
/// Vi (`Vi`, 254).
|
/// Vi (`Vi`, 254).
|
||||||
#[strum(to_string="Vi")] Vi = 254,
|
#[strum(to_string="Vi")] Vi = 254,
|
||||||
/// Viego (`Viego`, 234).
|
/// Viego (`Viego`, 234).
|
||||||
|
@ -369,6 +373,7 @@ impl Champion {
|
||||||
Self::Aatrox => "Aatrox",
|
Self::Aatrox => "Aatrox",
|
||||||
Self::Ahri => "Ahri",
|
Self::Ahri => "Ahri",
|
||||||
Self::Akali => "Akali",
|
Self::Akali => "Akali",
|
||||||
|
Self::Akshan => "Akshan",
|
||||||
Self::Alistar => "Alistar",
|
Self::Alistar => "Alistar",
|
||||||
Self::Amumu => "Amumu",
|
Self::Amumu => "Amumu",
|
||||||
Self::Anivia => "Anivia",
|
Self::Anivia => "Anivia",
|
||||||
|
@ -501,6 +506,7 @@ impl Champion {
|
||||||
Self::Vayne => "Vayne",
|
Self::Vayne => "Vayne",
|
||||||
Self::Veigar => "Veigar",
|
Self::Veigar => "Veigar",
|
||||||
Self::VelKoz => "Velkoz",
|
Self::VelKoz => "Velkoz",
|
||||||
|
Self::Vex => "Vex",
|
||||||
Self::Vi => "Vi",
|
Self::Vi => "Vi",
|
||||||
Self::Viego => "Viego",
|
Self::Viego => "Viego",
|
||||||
Self::Viktor => "Viktor",
|
Self::Viktor => "Viktor",
|
||||||
|
|
|
@ -58,6 +58,8 @@ pub enum GameMode {
|
||||||
TUTORIAL_MODULE_2,
|
TUTORIAL_MODULE_2,
|
||||||
/// Tutorial: Shop for Gear.
|
/// Tutorial: Shop for Gear.
|
||||||
TUTORIAL_MODULE_3,
|
TUTORIAL_MODULE_3,
|
||||||
|
/// Ultimate Spellbook games.
|
||||||
|
ULTBOOK,
|
||||||
/// URF games
|
/// URF games
|
||||||
URF,
|
URF,
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,6 +241,8 @@ pub enum Queue {
|
||||||
NEXUS_BLITZ_NEXUS_BLITZ_DEPRECATED_1200 = 1200,
|
NEXUS_BLITZ_NEXUS_BLITZ_DEPRECATED_1200 = 1200,
|
||||||
/// Nexus Blitz games on Nexus Blitz
|
/// Nexus Blitz games on Nexus Blitz
|
||||||
NEXUS_BLITZ_NEXUS_BLITZ = 1300,
|
NEXUS_BLITZ_NEXUS_BLITZ = 1300,
|
||||||
|
/// Ultimate Spellbook games on Summoner's Rift
|
||||||
|
SUMMONERS_RIFT_ULTIMATE_SPELLBOOK = 1400,
|
||||||
/// Tutorial 1 games on Summoner's Rift
|
/// Tutorial 1 games on Summoner's Rift
|
||||||
SUMMONERS_RIFT_TUTORIAL_1 = 2000,
|
SUMMONERS_RIFT_TUTORIAL_1 = 2000,
|
||||||
/// Tutorial 2 games on Summoner's Rift
|
/// Tutorial 2 games on Summoner's Rift
|
||||||
|
|
144
src/endpoints.rs
144
src/endpoints.rs
|
@ -7,7 +7,7 @@
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
||||||
// Version bbfb64a2ef9111c6610a823da800b0335587831d
|
// Version 1f61128ea79f3d07bd47c2f585e9f22905bed753
|
||||||
|
|
||||||
//! Automatically generated endpoint handles.
|
//! Automatically generated endpoint handles.
|
||||||
|
|
||||||
|
@ -140,15 +140,6 @@ impl RiotApi {
|
||||||
pub fn lor_status_v1(&self) -> LorStatusV1 {
|
pub fn lor_status_v1(&self) -> LorStatusV1 {
|
||||||
LorStatusV1 { base: self }
|
LorStatusV1 { base: self }
|
||||||
}
|
}
|
||||||
/// Returns a handle for accessing [MatchV4](crate::endpoints::MatchV4) endpoints.
|
|
||||||
/// # Riot Developer API Reference
|
|
||||||
/// <a href="https://developer.riotgames.com/apis#match-v4" target="_blank">`match-v4`</a>
|
|
||||||
///
|
|
||||||
/// Note: this method is automatically generated.
|
|
||||||
#[inline]
|
|
||||||
pub fn match_v4(&self) -> MatchV4 {
|
|
||||||
MatchV4 { base: self }
|
|
||||||
}
|
|
||||||
/// Returns a handle for accessing [MatchV5](crate::endpoints::MatchV5) endpoints.
|
/// Returns a handle for accessing [MatchV5](crate::endpoints::MatchV5) endpoints.
|
||||||
/// # Riot Developer API Reference
|
/// # Riot Developer API Reference
|
||||||
/// <a href="https://developer.riotgames.com/apis#match-v5" target="_blank">`match-v5`</a>
|
/// <a href="https://developer.riotgames.com/apis#match-v5" target="_blank">`match-v5`</a>
|
||||||
|
@ -799,117 +790,6 @@ impl<'a> LorStatusV1<'a> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// MatchV4 endpoints handle, accessed by calling [`match_v4()`](crate::RiotApi::match_v4) on a [`RiotApi`](crate::RiotApi) instance.
|
|
||||||
/// # Riot Developer API Reference
|
|
||||||
/// <a href="https://developer.riotgames.com/apis#match-v4" target="_blank">`match-v4`</a>
|
|
||||||
///
|
|
||||||
/// Note: this struct is automatically generated.
|
|
||||||
pub struct MatchV4<'a> {
|
|
||||||
base: &'a RiotApi,
|
|
||||||
}
|
|
||||||
impl<'a> MatchV4<'a> {
|
|
||||||
/// Get match IDs by tournament code.
|
|
||||||
/// # Parameters
|
|
||||||
/// * `region` - Region to query.
|
|
||||||
/// * `tournamentCode` - The tournament code.
|
|
||||||
/// # Riot Developer API Reference
|
|
||||||
/// <a href="https://developer.riotgames.com/api-methods/#match-v4/GET_getMatchIdsByTournamentCode" target="_blank">`match-v4.getMatchIdsByTournamentCode`</a>
|
|
||||||
///
|
|
||||||
/// Note: this method is automatically generated.
|
|
||||||
pub fn get_match_ids_by_tournament_code(&self, region: Region, tournament_code: &str)
|
|
||||||
-> impl Future<Output = Result<Vec<i64>>> + 'a
|
|
||||||
{
|
|
||||||
let path_string = format!("/lol/match/v4/matches/by-tournament-code/{}/ids", tournament_code);
|
|
||||||
self.base.get::<Vec<i64>>("match-v4.getMatchIdsByTournamentCode", region.into(), path_string, None)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get match by match ID.
|
|
||||||
/// # Parameters
|
|
||||||
/// * `region` - Region to query.
|
|
||||||
/// * `matchId` - The match ID.
|
|
||||||
/// # Riot Developer API Reference
|
|
||||||
/// <a href="https://developer.riotgames.com/api-methods/#match-v4/GET_getMatch" target="_blank">`match-v4.getMatch`</a>
|
|
||||||
///
|
|
||||||
/// Note: this method is automatically generated.
|
|
||||||
pub fn get_match(&self, region: Region, match_id: i64)
|
|
||||||
-> impl Future<Output = Result<Option<match_v4::Match>>> + 'a
|
|
||||||
{
|
|
||||||
let path_string = format!("/lol/match/v4/matches/{}", match_id);
|
|
||||||
self.base.get_optional::<match_v4::Match>("match-v4.getMatch", region.into(), path_string, None)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get match by match ID and tournament code.
|
|
||||||
/// # Parameters
|
|
||||||
/// * `region` - Region to query.
|
|
||||||
/// * `tournamentCode` - The tournament code.
|
|
||||||
/// * `matchId` - The match ID.
|
|
||||||
/// # Riot Developer API Reference
|
|
||||||
/// <a href="https://developer.riotgames.com/api-methods/#match-v4/GET_getMatchByTournamentCode" target="_blank">`match-v4.getMatchByTournamentCode`</a>
|
|
||||||
///
|
|
||||||
/// Note: this method is automatically generated.
|
|
||||||
pub fn get_match_by_tournament_code(&self, region: Region, match_id: i64, tournament_code: &str)
|
|
||||||
-> impl Future<Output = Result<match_v4::Match>> + 'a
|
|
||||||
{
|
|
||||||
let path_string = format!("/lol/match/v4/matches/{}/by-tournament-code/{}", match_id, tournament_code);
|
|
||||||
self.base.get::<match_v4::Match>("match-v4.getMatchByTournamentCode", region.into(), path_string, None)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get matchlist for games played on given account ID and platform ID and filtered using given filter parameters, if any.
|
|
||||||
/// ## Implementation Notes
|
|
||||||
/// A number of optional parameters are provided for filtering. It is up to the caller to ensure that the combination of filter parameters provided is valid for the requested account, otherwise, no matches may be returned.
|
|
||||||
///
|
|
||||||
/// 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.
|
|
||||||
///
|
|
||||||
/// 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.
|
|
||||||
/// # Parameters
|
|
||||||
/// * `region` - Region to query.
|
|
||||||
/// * `encryptedAccountId` - The account ID.
|
|
||||||
/// * `champion` (optional) - Set of champion IDs for filtering the matchlist.
|
|
||||||
/// * `queue` (optional) - Set of queue IDs for filtering the matchlist.
|
|
||||||
/// * `season` (optional) - [DEPRECATED] This field should not be considered reliable for the purposes of filtering matches by season.
|
|
||||||
/// * `endTime` (optional) - The end 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.
|
|
||||||
/// * `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.
|
|
||||||
/// # Riot Developer API Reference
|
|
||||||
/// <a href="https://developer.riotgames.com/api-methods/#match-v4/GET_getMatchlist" target="_blank">`match-v4.getMatchlist`</a>
|
|
||||||
///
|
|
||||||
/// Note: this method is automatically generated.
|
|
||||||
pub fn get_matchlist(&self, region: Region, encrypted_account_id: &str, begin_time: Option<i64>, begin_index: Option<i32>, champion: Option<&[crate::consts::Champion]>, end_time: Option<i64>, end_index: Option<i32>, queue: Option<&[crate::consts::Queue]>, season: Option<&[crate::consts::Season]>)
|
|
||||||
-> impl Future<Output = Result<Option<match_v4::Matchlist>>> + 'a
|
|
||||||
{
|
|
||||||
let mut query_params = Serializer::new(String::new());
|
|
||||||
if let Some(begin_time) = begin_time { query_params.append_pair("beginTime", &*begin_time.to_string()); };
|
|
||||||
if let Some(begin_index) = begin_index { query_params.append_pair("beginIndex", &*begin_index.to_string()); };
|
|
||||||
if let Some(champion) = champion { query_params.extend_pairs(champion.iter().map(|w| ("champion", Into::<i16>::into(*w).to_string()))); };
|
|
||||||
if let Some(end_time) = end_time { query_params.append_pair("endTime", &*end_time.to_string()); };
|
|
||||||
if let Some(end_index) = end_index { query_params.append_pair("endIndex", &*end_index.to_string()); };
|
|
||||||
if let Some(queue) = queue { query_params.extend_pairs(queue.iter().map(|w| ("queue", Into::<u16>::into(*w).to_string()))); };
|
|
||||||
if let Some(season) = season { query_params.extend_pairs(season.iter().map(|w| ("season", Into::<u8>::into(*w).to_string()))); };
|
|
||||||
let query_string = query_params.finish();
|
|
||||||
let path_string = format!("/lol/match/v4/matchlists/by-account/{}", encrypted_account_id);
|
|
||||||
self.base.get_optional::<match_v4::Matchlist>("match-v4.getMatchlist", region.into(), path_string, Some(query_string))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get match timeline by match ID.
|
|
||||||
/// ## Implementation Notes
|
|
||||||
/// Not all matches have timeline data.
|
|
||||||
/// # Parameters
|
|
||||||
/// * `region` - Region to query.
|
|
||||||
/// * `matchId` - The match ID.
|
|
||||||
/// # Riot Developer API Reference
|
|
||||||
/// <a href="https://developer.riotgames.com/api-methods/#match-v4/GET_getMatchTimeline" target="_blank">`match-v4.getMatchTimeline`</a>
|
|
||||||
///
|
|
||||||
/// Note: this method is automatically generated.
|
|
||||||
pub fn get_match_timeline(&self, region: Region, match_id: i64)
|
|
||||||
-> impl Future<Output = Result<Option<match_v4::MatchTimeline>>> + 'a
|
|
||||||
{
|
|
||||||
let path_string = format!("/lol/match/v4/timelines/by-match/{}", match_id);
|
|
||||||
self.base.get_optional::<match_v4::MatchTimeline>("match-v4.getMatchTimeline", region.into(), path_string, None)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// MatchV5 endpoints handle, accessed by calling [`match_v5()`](crate::RiotApi::match_v5) on a [`RiotApi`](crate::RiotApi) instance.
|
/// MatchV5 endpoints handle, accessed by calling [`match_v5()`](crate::RiotApi::match_v5) on a [`RiotApi`](crate::RiotApi) instance.
|
||||||
/// # Riot Developer API Reference
|
/// # Riot Developer API Reference
|
||||||
/// <a href="https://developer.riotgames.com/apis#match-v5" target="_blank">`match-v5`</a>
|
/// <a href="https://developer.riotgames.com/apis#match-v5" target="_blank">`match-v5`</a>
|
||||||
|
@ -923,18 +803,26 @@ impl<'a> MatchV5<'a> {
|
||||||
/// # Parameters
|
/// # Parameters
|
||||||
/// * `region` - Region to query.
|
/// * `region` - Region to query.
|
||||||
/// * `puuid`
|
/// * `puuid`
|
||||||
|
/// * `startTime` (optional) - Epoch timestamp in seconds. The matchlist started storing timestamps on June 16th, 2021. Any matches played before June 16th, 2021 won't be included in the results if the startTime filter is set.
|
||||||
|
/// * `endTime` (optional) - Epoch timestamp in seconds.
|
||||||
|
/// * `queue` (optional) - Filter the list of match ids by a specific queue id. This filter is mutually inclusive of the type filter meaning any match ids returned must match both the queue and type filters.
|
||||||
|
/// * `type` (optional) - Filter the list of match ids by the type of match. This filter is mutually inclusive of the queue filter meaning any match ids returned must match both the queue and type filters.
|
||||||
/// * `start` (optional) - Defaults to 0. Start index.
|
/// * `start` (optional) - Defaults to 0. Start index.
|
||||||
/// * `count` (optional) - Defaults to 20. Valid values: 0 to 100. Match id count.
|
/// * `count` (optional) - Defaults to 20. Valid values: 0 to 100. Number of match ids to return.
|
||||||
/// # Riot Developer API Reference
|
/// # Riot Developer API Reference
|
||||||
/// <a href="https://developer.riotgames.com/api-methods/#match-v5/GET_getMatchIdsByPUUID" target="_blank">`match-v5.getMatchIdsByPUUID`</a>
|
/// <a href="https://developer.riotgames.com/api-methods/#match-v5/GET_getMatchIdsByPUUID" target="_blank">`match-v5.getMatchIdsByPUUID`</a>
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
pub fn get_match_ids_by_puuid(&self, region: Region, puuid: &str, count: Option<i32>, start: Option<i32>)
|
pub fn get_match_ids_by_puuid(&self, region: Region, puuid: &str, count: Option<i32>, end_time: Option<i64>, queue: Option<crate::consts::Queue>, start_time: Option<i64>, start: Option<i32>, r#type: Option<&str>)
|
||||||
-> impl Future<Output = Result<Vec<String>>> + 'a
|
-> impl Future<Output = Result<Vec<String>>> + 'a
|
||||||
{
|
{
|
||||||
let mut query_params = Serializer::new(String::new());
|
let mut query_params = Serializer::new(String::new());
|
||||||
if let Some(count) = count { query_params.append_pair("count", &*count.to_string()); };
|
if let Some(count) = count { query_params.append_pair("count", &*count.to_string()); };
|
||||||
|
if let Some(end_time) = end_time { query_params.append_pair("endTime", &*end_time.to_string()); };
|
||||||
|
if let Some(queue) = queue { query_params.append_pair("queue", &*Into::<u16>::into(queue).to_string()); };
|
||||||
|
if let Some(start_time) = start_time { query_params.append_pair("startTime", &*start_time.to_string()); };
|
||||||
if let Some(start) = start { query_params.append_pair("start", &*start.to_string()); };
|
if let Some(start) = start { query_params.append_pair("start", &*start.to_string()); };
|
||||||
|
if let Some(r#type) = r#type { query_params.append_pair("type", r#type); };
|
||||||
let query_string = query_params.finish();
|
let query_string = query_params.finish();
|
||||||
let path_string = format!("/lol/match/v5/matches/by-puuid/{}/ids", puuid);
|
let path_string = format!("/lol/match/v5/matches/by-puuid/{}/ids", puuid);
|
||||||
self.base.get::<Vec<String>>("match-v5.getMatchIdsByPUUID", region.into(), path_string, Some(query_string))
|
self.base.get::<Vec<String>>("match-v5.getMatchIdsByPUUID", region.into(), path_string, Some(query_string))
|
||||||
|
@ -949,10 +837,10 @@ impl<'a> MatchV5<'a> {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
pub fn get_match(&self, region: Region, match_id: &str)
|
pub fn get_match(&self, region: Region, match_id: &str)
|
||||||
-> impl Future<Output = Result<match_v5::Match>> + 'a
|
-> impl Future<Output = Result<Option<match_v5::Match>>> + 'a
|
||||||
{
|
{
|
||||||
let path_string = format!("/lol/match/v5/matches/{}", match_id);
|
let path_string = format!("/lol/match/v5/matches/{}", match_id);
|
||||||
self.base.get::<match_v5::Match>("match-v5.getMatch", region.into(), path_string, None)
|
self.base.get_optional::<match_v5::Match>("match-v5.getMatch", region.into(), path_string, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a match timeline by match id
|
/// Get a match timeline by match id
|
||||||
|
@ -964,10 +852,10 @@ impl<'a> MatchV5<'a> {
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
pub fn get_timeline(&self, region: Region, match_id: &str)
|
pub fn get_timeline(&self, region: Region, match_id: &str)
|
||||||
-> impl Future<Output = Result<match_v5::MatchTimeline>> + 'a
|
-> impl Future<Output = Result<Option<match_v5::MatchTimeline>>> + 'a
|
||||||
{
|
{
|
||||||
let path_string = format!("/lol/match/v5/matches/{}/timeline", match_id);
|
let path_string = format!("/lol/match/v5/matches/{}/timeline", match_id);
|
||||||
self.base.get::<match_v5::MatchTimeline>("match-v5.getTimeline", region.into(), path_string, None)
|
self.base.get_optional::<match_v5::MatchTimeline>("match-v5.getTimeline", region.into(), path_string, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1131,7 +1019,7 @@ impl<'a> TftLeagueV1<'a> {
|
||||||
/// <a href="https://developer.riotgames.com/api-methods/#tft-league-v1/GET_getLeagueEntries" target="_blank">`tft-league-v1.getLeagueEntries`</a>
|
/// <a href="https://developer.riotgames.com/api-methods/#tft-league-v1/GET_getLeagueEntries" target="_blank">`tft-league-v1.getLeagueEntries`</a>
|
||||||
///
|
///
|
||||||
/// Note: this method is automatically generated.
|
/// Note: this method is automatically generated.
|
||||||
pub fn get_league_entries(&self, region: Region, tier: &str, division: &str, page: Option<i32>)
|
pub fn get_league_entries(&self, region: Region, tier: crate::consts::Tier, division: &str, page: Option<i32>)
|
||||||
-> impl Future<Output = Result<Vec<tft_league_v1::LeagueEntry>>> + 'a
|
-> impl Future<Output = Result<Vec<tft_league_v1::LeagueEntry>>> + 'a
|
||||||
{
|
{
|
||||||
let mut query_params = Serializer::new(String::new());
|
let mut query_params = Serializer::new(String::new());
|
||||||
|
|
154
src/lib.rs
154
src/lib.rs
|
@ -1,10 +1,156 @@
|
||||||
#![cfg_attr(feature = "nightly", feature(non_exhaustive))]
|
///////////////////////////////////////////////
|
||||||
#![cfg_attr(feature = "nightly", feature(external_doc))]
|
// //
|
||||||
|
// ! //
|
||||||
|
// This file is automatically generated! //
|
||||||
|
// Do not directly edit! //
|
||||||
|
// //
|
||||||
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
|
|
||||||
#![cfg_attr(feature = "nightly", doc(include = "../README.md"))]
|
//! <h1 align="center">
|
||||||
#![cfg_attr(not(feature = "nightly"), doc = "See [README.md](https://github.com/MingweiSamuel/Riven#readme).")]
|
//! Riven<br>
|
||||||
|
//! </h1>
|
||||||
|
//! <p align="center">
|
||||||
|
//! <a href="https://github.com/MingweiSamuel/Riven/"><img src="https://cdn.communitydragon.org/latest/champion/Riven/square" width="20" height="20" alt="Riven Github"></a>
|
||||||
|
//! <a href="https://crates.io/crates/riven"><img src="https://img.shields.io/crates/v/riven?style=flat-square&logo=rust" alt="Crates.io"></a>
|
||||||
|
//! <a href="https://docs.rs/riven/"><img src="https://img.shields.io/badge/docs.rs-Riven-blue?style=flat-square&logo=read-the-docs&logoColor=white" alt="Docs.rs"></a>
|
||||||
|
//! <a href="https://travis-ci.com/MingweiSamuel/Riven"><img src="https://img.shields.io/travis/com/mingweisamuel/riven?style=flat-square" alt="Travis CI"></a>
|
||||||
|
//! <a href="https://github.com/rust-secure-code/safety-dance/"><img src="https://img.shields.io/badge/unsafe-forbidden-green.svg?style=flat-square" alt="unsafe forbidden"></a>
|
||||||
|
//! </p>
|
||||||
|
//!
|
||||||
|
//! Rust Library for the [Riot Games API](https://developer.riotgames.com/).
|
||||||
|
//!
|
||||||
|
//! Riven's goals are _speed_, _reliability_, and _maintainability_. Riven handles rate limits and large requests with ease.
|
||||||
|
//! Data structs and endpoints are automatically generated from the
|
||||||
|
//! [Riot API Reference](https://developer.riotgames.com/api-methods/) ([Swagger](http://www.mingweisamuel.com/riotapi-schema/tool/)).
|
||||||
|
//!
|
||||||
|
//! ## Design
|
||||||
|
//!
|
||||||
|
//! * Fast, asynchronous, thread-safe.
|
||||||
|
//! * Automatically retries failed requests.
|
||||||
|
//! * TFT API Support.
|
||||||
|
//!
|
||||||
|
//! ## Usage
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! use riven::RiotApi;
|
||||||
|
//! use riven::consts::Region;
|
||||||
|
//!
|
||||||
|
//! // Enter tokio async runtime.
|
||||||
|
//! let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
//! rt.block_on(async {
|
||||||
|
//! // Create RiotApi instance from key string.
|
||||||
|
//! let api_key = "RGAPI-01234567-89ab-cdef-0123-456789abcdef";
|
||||||
|
//! # /* (doc testing) */ let api_key = std::env!("RGAPI_KEY");
|
||||||
|
//! let riot_api = RiotApi::with_key(api_key);
|
||||||
|
//!
|
||||||
|
//! // Get summoner data.
|
||||||
|
//! let summoner = riot_api.summoner_v4()
|
||||||
|
//! .get_by_summoner_name(Region::NA, "잘 못").await
|
||||||
|
//! .expect("Get summoner failed.")
|
||||||
|
//! .expect("There is no summoner with that name.");
|
||||||
|
//!
|
||||||
|
//! // Print summoner name.
|
||||||
|
//! println!("{} Champion Masteries:", summoner.name);
|
||||||
|
//!
|
||||||
|
//! // Get champion mastery data.
|
||||||
|
//! let masteries = riot_api.champion_mastery_v4()
|
||||||
|
//! .get_all_champion_masteries(Region::NA, &summoner.id).await
|
||||||
|
//! .expect("Get champion masteries failed.");
|
||||||
|
//!
|
||||||
|
//! // Print champioon masteries.
|
||||||
|
//! for (i, mastery) in masteries.iter().take(10).enumerate() {
|
||||||
|
//! println!("{: >2}) {: <9} {: >7} ({})", i + 1,
|
||||||
|
//! mastery.champion_id.to_string(),
|
||||||
|
//! mastery.champion_points, mastery.champion_level);
|
||||||
|
//! }
|
||||||
|
//! });
|
||||||
|
//! ```
|
||||||
|
//! Output:
|
||||||
|
//! ```text
|
||||||
|
//! 잘 못 Champion Masteries:
|
||||||
|
//! 1) Riven 1219895 (7)
|
||||||
|
//! 2) Fiora 229714 (5)
|
||||||
|
//! 3) Katarina 175985 (5)
|
||||||
|
//! 4) Lee Sin 150546 (7)
|
||||||
|
//! 5) Jax 100509 (5)
|
||||||
|
//! 6) Gnar 76373 (6)
|
||||||
|
//! 7) Kai'Sa 64271 (5)
|
||||||
|
//! 8) Caitlyn 46479 (5)
|
||||||
|
//! 9) Irelia 46465 (5)
|
||||||
|
//! 10) Vladimir 37176 (5)
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! ### Nightly vs Stable
|
||||||
|
//!
|
||||||
|
//! Enable the `nightly` feature to use nightly-only functionality. Mainly enables
|
||||||
|
//! [nightly optimizations in the `parking_lot` crate](https://github.com/Amanieu/parking_lot#nightly-vs-stable).
|
||||||
|
//! Also required for running async integration tests.
|
||||||
|
//!
|
||||||
|
//! ### Docs
|
||||||
|
//!
|
||||||
|
//! [On docs.rs](https://docs.rs/riven/).
|
||||||
|
//!
|
||||||
|
//! ### Error Handling
|
||||||
|
//!
|
||||||
|
//! Riven returns either `Result<T>` or `Result<Option<T>>` within futures.
|
||||||
|
//!
|
||||||
|
//! If the `Result` is errored, this indicates that the API request failed to
|
||||||
|
//! complete successfully, which may be due to bad user input, Riot server errors,
|
||||||
|
//! incorrect API key, etc.
|
||||||
|
//!
|
||||||
|
//! If the `Option` is `None`, this indicates that the request completed
|
||||||
|
//! successfully but no data was returned. This happens in several situations, such
|
||||||
|
//! as getting a summoner (by name) or match (by id) that doesn't exist, or getting
|
||||||
|
//! spectator data for a summoner who is not in-game.
|
||||||
|
//! Specifically, the API returned a 404 HTTP status code in this situation.
|
||||||
|
//!
|
||||||
|
//! The error type used by Riven is `riven::RiotApiError`. It provides some basic
|
||||||
|
//! diagnostic information, such as the source Reqwest error, the number of retries
|
||||||
|
//! attempted, and the Reqwest `Response` object.
|
||||||
|
//!
|
||||||
|
//! You can configure the number of time Riven retries using
|
||||||
|
//! `RiotApiConfig::set_retries(...)` and the `RiotApi::with_config(config)`
|
||||||
|
//! constructor. By default, Riven retries up to 3 times (4 requests total).
|
||||||
|
//! Some errors, such as 400 client errors, are not retried as they would
|
||||||
|
//! inevitably fail again.
|
||||||
|
//!
|
||||||
|
//! ### Semantic Versioning
|
||||||
|
//!
|
||||||
|
//! This package follows semantic versioning to an extent. However, the Riot API
|
||||||
|
//! itself changes often and does not follow semantic versioning, which makes
|
||||||
|
//! things difficult. Out-of-date versions will slowly partially cease to work due
|
||||||
|
//! to this.
|
||||||
|
//!
|
||||||
|
//! When the API changes, this may result in breaking changes in the `models`
|
||||||
|
//! module, `endpoints` module, and some of the `consts` module. "Handle accessor"
|
||||||
|
//! methods may be removed from `RiotApi` if the corresponding endpoint is removed
|
||||||
|
//! from the Riot API. These breaking changes will increment the **MINOR** version,
|
||||||
|
//! not the major version.
|
||||||
|
//!
|
||||||
|
//! Parts of Riven that do not depend on Riot API changes do follow semantic
|
||||||
|
//! versioning.
|
||||||
|
//!
|
||||||
|
//! ### Additional Help
|
||||||
|
//!
|
||||||
|
//! Feel free to [make an issue](https://github.com/MingweiSamuel/Riven/issues/new)
|
||||||
|
//! if you are have any questions or trouble with Riven.
|
||||||
|
//!
|
||||||
|
//! ## Development
|
||||||
|
//!
|
||||||
|
//! NodeJS is used to generate code for Riven. The
|
||||||
|
//! [`srcgen/`](https://github.com/MingweiSamuel/Riven/tree/master/srcgen)
|
||||||
|
//! folder contains the code and [doT.js](https://olado.github.io/doT/index.html)
|
||||||
|
//! templates. `index.js` lists the JSON files downloaded and used to generate the
|
||||||
|
//! code.
|
||||||
|
//!
|
||||||
|
//! To set up the srcgen, you will first need to install NodeJS. Then enter the
|
||||||
|
//! srcgen folder and run `npm ci` (or `npm install`) to install dependencies.
|
||||||
|
//!
|
||||||
|
//! To run the srcgen use `node srcgen` from the main folder.
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
|
||||||
// Re-exported reqwest types.
|
// Re-exported reqwest types.
|
||||||
pub use reqwest;
|
pub use reqwest;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
// http://www.mingweisamuel.com/riotapi-schema/tool/
|
||||||
// Version bbfb64a2ef9111c6610a823da800b0335587831d
|
// Version 1f61128ea79f3d07bd47c2f585e9f22905bed753
|
||||||
|
|
||||||
//! Metadata about the Riot API and Riven.
|
//! Metadata about the Riot API and Riven.
|
||||||
//!
|
//!
|
||||||
|
@ -45,11 +45,6 @@ lazy_static! {
|
||||||
map.insert("/lor/match/v1/matches/{matchId}", "lor-match-v1.getMatch");
|
map.insert("/lor/match/v1/matches/{matchId}", "lor-match-v1.getMatch");
|
||||||
map.insert("/lor/ranked/v1/leaderboards", "lor-ranked-v1.getLeaderboards");
|
map.insert("/lor/ranked/v1/leaderboards", "lor-ranked-v1.getLeaderboards");
|
||||||
map.insert("/lor/status/v1/platform-data", "lor-status-v1.getPlatformData");
|
map.insert("/lor/status/v1/platform-data", "lor-status-v1.getPlatformData");
|
||||||
map.insert("/lol/match/v4/matches/by-tournament-code/{tournamentCode}/ids", "match-v4.getMatchIdsByTournamentCode");
|
|
||||||
map.insert("/lol/match/v4/matches/{matchId}", "match-v4.getMatch");
|
|
||||||
map.insert("/lol/match/v4/matches/{matchId}/by-tournament-code/{tournamentCode}", "match-v4.getMatchByTournamentCode");
|
|
||||||
map.insert("/lol/match/v4/matchlists/by-account/{encryptedAccountId}", "match-v4.getMatchlist");
|
|
||||||
map.insert("/lol/match/v4/timelines/by-match/{matchId}", "match-v4.getMatchTimeline");
|
|
||||||
map.insert("/lol/match/v5/matches/by-puuid/{puuid}/ids", "match-v5.getMatchIdsByPUUID");
|
map.insert("/lol/match/v5/matches/by-puuid/{puuid}/ids", "match-v5.getMatchIdsByPUUID");
|
||||||
map.insert("/lol/match/v5/matches/{matchId}", "match-v5.getMatch");
|
map.insert("/lol/match/v5/matches/{matchId}", "match-v5.getMatch");
|
||||||
map.insert("/lol/match/v5/matches/{matchId}/timeline", "match-v5.getTimeline");
|
map.insert("/lol/match/v5/matches/{matchId}/timeline", "match-v5.getTimeline");
|
||||||
|
|
1304
src/models.rs
1304
src/models.rs
File diff suppressed because it is too large
Load Diff
|
@ -68,9 +68,7 @@ impl VectorTokenBucket {
|
||||||
|
|
||||||
// Effective duration.
|
// Effective duration.
|
||||||
let d_eff = duration + duration_overhead;
|
let d_eff = duration + duration_overhead;
|
||||||
let burst_duration = Duration::new(
|
let burst_duration = d_eff.mul_f32(burst_pct);
|
||||||
(d_eff.as_secs() as f32 * burst_pct).ceil() as u64,
|
|
||||||
(d_eff.subsec_nanos() as f32 * burst_pct).ceil() as u32);
|
|
||||||
let burst_limit = std::cmp::max(1,
|
let burst_limit = std::cmp::max(1,
|
||||||
(total_limit as f32 * burst_pct).floor() as usize);
|
(total_limit as f32 * burst_pct).floor() as usize);
|
||||||
debug_assert!(burst_limit <= total_limit);
|
debug_assert!(burst_limit <= total_limit);
|
||||||
|
@ -137,7 +135,21 @@ impl TokenBucket for VectorTokenBucket {
|
||||||
for _ in 0..n {
|
for _ in 0..n {
|
||||||
timestamps.push_front(now);
|
timestamps.push_front(now);
|
||||||
}
|
}
|
||||||
timestamps.len() <= self.total_limit
|
|
||||||
|
// Check total limit.
|
||||||
|
if self.total_limit < timestamps.len() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check burst limit.
|
||||||
|
if let Some(burst_time) = timestamps.get(self.burst_limit) {
|
||||||
|
let duration_since = now.duration_since(*burst_time); // `now` before `burst_time` will panic.
|
||||||
|
if duration_since < self.burst_duration {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_bucket_duration(&self) -> Duration {
|
fn get_bucket_duration(&self) -> Duration {
|
||||||
|
|
|
@ -32,46 +32,42 @@ mod token_bucket {
|
||||||
assert_eq!(1, bucket.burst_limit);
|
assert_eq!(1, bucket.burst_limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_saturated_100_burst() {
|
|
||||||
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, *D00, 1.00);
|
|
||||||
|
|
||||||
Instant::set_time(50_000);
|
|
||||||
assert!(bucket.get_tokens(100), "All tokens should be immediately available.");
|
|
||||||
assert_ne!(None, bucket.get_delay(), "Bucket should have delay.");
|
|
||||||
|
|
||||||
Instant::advance_time(1001); // Extra buffer for Duration(0).
|
|
||||||
assert!(bucket.get_tokens(100), "All tokens should be available after a bucket duration.");
|
|
||||||
assert_ne!(None, bucket.get_delay(), "Bucket should have delay.");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_saturated_95_burst() {
|
fn test_saturated_95_burst() {
|
||||||
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, *D00, 0.50);
|
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, *D00, 0.95);
|
||||||
|
|
||||||
Instant::set_time(50_000);
|
Instant::set_time(50_000);
|
||||||
assert!(bucket.get_tokens(95), "95 tokens should be immediately available.");
|
assert!(bucket.get_tokens(95), "95 tokens should be immediately available.");
|
||||||
assert_ne!(None, bucket.get_delay(), "Bucket should have delay.");
|
assert_ne!(None, bucket.get_delay(), "Bucket should have delay.");
|
||||||
|
|
||||||
Instant::advance_time(475); // Total 951.
|
Instant::advance_time(475);
|
||||||
assert_ne!(None, bucket.get_delay(), "Bucket should have delay.");
|
assert_ne!(None, bucket.get_delay(), "Bucket should have delay.");
|
||||||
|
Instant::advance_time(476); // Total 951. Extra buffer for Duration(0).
|
||||||
|
|
||||||
Instant::advance_time(476); // Extra buffer for Duration(0).
|
|
||||||
assert!(bucket.get_tokens(5), "Last 5 tokens should be available.");
|
assert!(bucket.get_tokens(5), "Last 5 tokens should be available.");
|
||||||
assert_ne!(None, bucket.get_delay(), "Bucket should have delay.");
|
assert_ne!(None, bucket.get_delay(), "Bucket should have delay.");
|
||||||
|
|
||||||
Instant::advance_time(51);
|
Instant::advance_time(51); // Total 1002.
|
||||||
assert!(bucket.get_tokens(95), "95 tokens should be available.");
|
assert!(bucket.get_tokens(90), "90 tokens should be available.");
|
||||||
assert_ne!(None, bucket.get_delay(), "Bucket should have delay.");
|
assert_ne!(None, bucket.get_delay(), "Bucket should have delay.");
|
||||||
|
|
||||||
Instant::advance_time(951);
|
Instant::advance_time(951);
|
||||||
assert!(bucket.get_tokens(5), "Last 5 tokens should be available.");
|
assert!(bucket.get_tokens(10), "Last 10 tokens should be available.");
|
||||||
|
assert_ne!(None, bucket.get_delay(), "Bucket should have delay.");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_violated_50_burst() {
|
||||||
|
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, *D00, 0.50);
|
||||||
|
|
||||||
|
Instant::set_time(50_000);
|
||||||
|
assert!(!bucket.get_tokens(90), "Burst should be violated.");
|
||||||
assert_ne!(None, bucket.get_delay(), "Bucket should have delay.");
|
assert_ne!(None, bucket.get_delay(), "Bucket should have delay.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_saturated_50_burst() {
|
fn test_saturated_50_burst() {
|
||||||
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, *D00, 0.5);
|
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, *D00, 0.50);
|
||||||
|
|
||||||
Instant::set_time(50_000);
|
Instant::set_time(50_000);
|
||||||
assert!(bucket.get_tokens(50), "Half the tokens should be immediately available.");
|
assert!(bucket.get_tokens(50), "Half the tokens should be immediately available.");
|
||||||
|
@ -93,18 +89,18 @@ mod token_bucket {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_many() {
|
fn test_many() {
|
||||||
Instant::set_time(50_000);
|
Instant::set_time(50_000);
|
||||||
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, *D00, 0.95);
|
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, *D00, 0.5);
|
||||||
assert!(bucket.get_tokens(50), "Should have not violated limit.");
|
assert!(bucket.get_tokens(50), "Should have not violated limit. i=-1.");
|
||||||
assert_eq!(None, bucket.get_delay(), "Should not be blocked.");
|
assert_ne!(None, bucket.get_delay(), "Bucket should have delay. i=-1.");
|
||||||
for _ in 0..20_000 {
|
for i in 0..20_000 {
|
||||||
Instant::advance_time(501);
|
Instant::advance_time(501);
|
||||||
assert!(bucket.get_tokens(50), "Should have not violated limit.");
|
assert!(bucket.get_tokens(50), "Should have not violated limit. i={}.", i);
|
||||||
assert_ne!(None, bucket.get_delay(), "Bucket should have delay.");
|
assert_ne!(None, bucket.get_delay(), "Bucket should have delay. i={}.", i);
|
||||||
Instant::advance_time(501);
|
Instant::advance_time(501);
|
||||||
assert!(bucket.get_tokens(50), "Should have not violated limit.");
|
assert!(bucket.get_tokens(50), "Should have not violated limit. i={}.", i);
|
||||||
assert_ne!(None, bucket.get_delay(), "Bucket should have delay.");
|
assert_ne!(None, bucket.get_delay(), "Bucket should have delay. i={}.", i);
|
||||||
}
|
}
|
||||||
assert!(bucket.timestamps.lock().len() < 110, "Check memory leak.");
|
assert!(bucket.timestamps.lock().len() < 110, "Should not memory leak.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,9 @@ function normalizeArgName(name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizePropName(propName) {
|
function normalizePropName(propName) {
|
||||||
const out = changeCase.snakeCase(propName);
|
let out = changeCase.snakeCase(propName);
|
||||||
|
if (/^\d/.test(out)) // No leading digits.
|
||||||
|
out = 'x' + out;
|
||||||
if ('type' === out)
|
if ('type' === out)
|
||||||
return 'r#' + out;
|
return 'r#' + out;
|
||||||
return out;
|
return out;
|
||||||
|
@ -112,8 +114,8 @@ function formatQueryParamStringify(name, prop, useOwned = false) {
|
||||||
if (prop['x-enum']) {
|
if (prop['x-enum']) {
|
||||||
switch (prop.type) {
|
switch (prop.type) {
|
||||||
case 'integer':
|
case 'integer':
|
||||||
return `${own}Into::<${enumTypeLookup[prop['x-enum']]}>::into(*${name}).to_string()`;
|
return `${own}Into::<${enumTypeLookup[prop['x-enum']]}>::into(${name}).to_string()`;
|
||||||
default: throw new Error(`Enum not supported: ${JSON.stringify(prop)}.`)
|
default: // Fall-through.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (prop.type) {
|
switch (prop.type) {
|
||||||
|
@ -125,10 +127,10 @@ function formatQueryParamStringify(name, prop, useOwned = false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatAddQueryParam(param) {
|
function formatAddQueryParam(param) {
|
||||||
let k = `"${param.name}"`;
|
const k = `"${param.name}"`;
|
||||||
let name = changeCase.snakeCase(param.name);
|
const name = normalizePropName(param.name);
|
||||||
let nc = param.required ? '' : `if let Some(${name}) = ${name} `;
|
const nc = param.required ? '' : `if let Some(${name}) = ${name} `;
|
||||||
let prop = param.schema;
|
const prop = param.schema;
|
||||||
switch (prop.type) {
|
switch (prop.type) {
|
||||||
case 'array': return `${nc}{ query_params.extend_pairs(${name}.iter()`
|
case 'array': return `${nc}{ query_params.extend_pairs(${name}.iter()`
|
||||||
+ `.map(|w| (${k}, ${formatQueryParamStringify("w", prop.items, true)}))); }`;
|
+ `.map(|w| (${k}, ${formatQueryParamStringify("w", prop.items, true)}))); }`;
|
||||||
|
|
|
@ -108,7 +108,7 @@ impl<'a> {{= endpoint }}<'a> {
|
||||||
let required = paramList === pathParams;
|
let required = paramList === pathParams;
|
||||||
for (let param of paramList)
|
for (let param of paramList)
|
||||||
{
|
{
|
||||||
argBuilder.push(', ', dotUtils.changeCase.snakeCase(param.name), ': ',
|
argBuilder.push(', ', dotUtils.normalizePropName(param.name), ': ',
|
||||||
dotUtils.stringifyType(param.schema, { endpoint, optional: !required, owned: false }));
|
dotUtils.stringifyType(param.schema, { endpoint, optional: !required, owned: false }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
{{
|
||||||
|
const dotUtils = require('./dotUtils.js');
|
||||||
|
const readme = require('fs').readFileSync('../README.md', 'utf-8').split(/\r?\n/);
|
||||||
|
}}{{= dotUtils.preamble() }}
|
||||||
|
|
||||||
|
#![forbid(unsafe_code)]
|
||||||
|
|
||||||
|
{{~ readme :line }}
|
||||||
|
//! {{= line }}
|
||||||
|
{{~}}
|
||||||
|
|
||||||
|
// Re-exported reqwest types.
|
||||||
|
pub use reqwest;
|
||||||
|
|
||||||
|
|
||||||
|
mod config;
|
||||||
|
pub use config::RiotApiConfig;
|
||||||
|
|
||||||
|
pub mod consts;
|
||||||
|
|
||||||
|
pub mod endpoints;
|
||||||
|
|
||||||
|
mod error;
|
||||||
|
pub use error::*;
|
||||||
|
|
||||||
|
pub mod meta;
|
||||||
|
|
||||||
|
pub mod models;
|
||||||
|
|
||||||
|
mod req;
|
||||||
|
|
||||||
|
mod response_info;
|
||||||
|
pub use response_info::*;
|
||||||
|
|
||||||
|
mod riot_api;
|
||||||
|
pub use riot_api::*;
|
||||||
|
|
||||||
|
mod util;
|
|
@ -15,7 +15,10 @@ macro_rules! async_tests {
|
||||||
println!();
|
println!();
|
||||||
println!("running tests");
|
println!("running tests");
|
||||||
println!();
|
println!();
|
||||||
|
|
||||||
|
#[allow(unused_mut)]
|
||||||
let mut oks: u32 = 0;
|
let mut oks: u32 = 0;
|
||||||
|
#[allow(unused_mut)]
|
||||||
let mut errs: u32 = 0;
|
let mut errs: u32 = 0;
|
||||||
$(
|
$(
|
||||||
let $name = async {
|
let $name = async {
|
||||||
|
@ -65,7 +68,7 @@ macro_rules! rassert {
|
||||||
};
|
};
|
||||||
( $x:expr, $format:expr $(, $arg:expr)* ) => {
|
( $x:expr, $format:expr $(, $arg:expr)* ) => {
|
||||||
{
|
{
|
||||||
if $x { Ok(()) } else { Err( format!($format, $( $arg )* ) ) }?
|
if $x { Ok(()) } else { Err( format!($format $(, $arg )* ) ) }?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
#![cfg_attr(feature = "nightly", feature(custom_test_frameworks))]
|
||||||
|
#![cfg_attr(feature = "nightly", test_runner(my_runner))]
|
||||||
|
|
||||||
|
mod async_tests;
|
||||||
|
mod testutils;
|
||||||
|
use testutils::*;
|
||||||
|
|
||||||
|
use colored::*;
|
||||||
|
|
||||||
|
use riven::consts::*;
|
||||||
|
|
||||||
|
static MATCHES: [&'static str; 3] = [ "NA1_3923487226", "NA1_4049206905", "NA1_4052515784" ];
|
||||||
|
|
||||||
|
async_tests!{
|
||||||
|
my_runner {
|
||||||
|
match_v5_get: async {
|
||||||
|
for matche in MATCHES {
|
||||||
|
let p = RIOT_API.match_v5().get_match(Region::AMERICAS, matche);
|
||||||
|
let m = p.await.map_err(|e| e.to_string())?.ok_or(format!("Match {} not found.", matche))?;
|
||||||
|
rassert_eq!(matche, m.metadata.match_id, "Bad match id? Sent {}, received {}.", matche, m.metadata.match_id);
|
||||||
|
rassert!(!m.metadata.participants.is_empty(), "Match should have participants.");
|
||||||
|
rassert!(!m.info.teams.is_empty(), "Match should have teams.");
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
match_v5_get_timeline: async {
|
||||||
|
for matche in MATCHES {
|
||||||
|
let p = RIOT_API.match_v5().get_timeline(Region::AMERICAS, matche);
|
||||||
|
let m = p.await.map_err(|e| e.to_string())?.ok_or(format!("Match timeline {} not found.", matche))?;
|
||||||
|
rassert_eq!(matche, m.metadata.match_id, "Bad match id? Sent {}, received {}.", matche, m.metadata.match_id);
|
||||||
|
rassert!(!m.metadata.participants.is_empty(), "Match should have participants.");
|
||||||
|
rassert_eq!(matche, format!("NA1_{}", m.info.game_id), "Match number ID should match.");
|
||||||
|
rassert!(!m.info.frames.is_empty(), "Match timleine should have frames.");
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,16 +47,17 @@ async_tests!{
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
|
|
||||||
// tft-league-v1.getLeagueEntriesForSummoner
|
// Disabled: Caihonbbt no longer ranked.
|
||||||
// https://github.com/MingweiSamuel/Riven/issues/25
|
// // tft-league-v1.getLeagueEntriesForSummoner
|
||||||
tft_league_getleagueentriesforsummoner: async {
|
// // https://github.com/MingweiSamuel/Riven/issues/25
|
||||||
let sp = RIOT_API.summoner_v4().get_by_summoner_name(Region::JP, "Caihonbbt");
|
// tft_league_getleagueentriesforsummoner: async {
|
||||||
let sr = sp.await.map_err(|e| e.to_string())?.ok_or("Failed to get \"Caihonbbt\"".to_owned())?;
|
// let sp = RIOT_API.summoner_v4().get_by_summoner_name(Region::JP, "Caihonbbt");
|
||||||
let lp = RIOT_API.tft_league_v1().get_league_entries_for_summoner(Region::JP, &sr.id);
|
// let sr = sp.await.map_err(|e| e.to_string())?.ok_or("Failed to get \"Caihonbbt\"".to_owned())?;
|
||||||
let lr = lp.await.map_err(|e| e.to_string())?;
|
// let lp = RIOT_API.tft_league_v1().get_league_entries_for_summoner(Region::JP, &sr.id);
|
||||||
rassert!(0 < lr.len());
|
// let lr = lp.await.map_err(|e| e.to_string())?;
|
||||||
Ok(())
|
// rassert!(0 < lr.len());
|
||||||
},
|
// Ok(())
|
||||||
|
// },
|
||||||
// tft-league-v1.getTopRatedLadder
|
// tft-league-v1.getTopRatedLadder
|
||||||
// https://github.com/MingweiSamuel/Riven/issues/24
|
// https://github.com/MingweiSamuel/Riven/issues/24
|
||||||
tft_league_gettopratedladder: async {
|
tft_league_gettopratedladder: async {
|
||||||
|
|
|
@ -46,77 +46,79 @@ async_tests!{
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
|
|
||||||
matchlist_get: async {
|
// TODO: MATCH-V4 REMOVED.
|
||||||
|
// matchlist_get: async {
|
||||||
|
// let sp = RIOT_API.summoner_v4().get_by_summoner_name(Region::NA, "haha yes");
|
||||||
|
// let s = sp.await.map_err(|e| e.to_string())?.ok_or("Failed to get \"haha yes\"".to_owned())?;
|
||||||
|
// let mp = RIOT_API.match_v4().get_matchlist(Region::NA, &s.account_id, None, Some(2500), None, None, Some(2600), None, None);
|
||||||
|
// let m = mp.await.map_err(|e| e.to_string())?.ok_or("Failed to get matchlist".to_owned())?;
|
||||||
|
// rassert!(m.matches.len() > 0, "Matchlist should not be empty");
|
||||||
|
// Ok(())
|
||||||
|
// },
|
||||||
|
|
||||||
let sp = RIOT_API.summoner_v4().get_by_summoner_name(Region::NA, "haha yes");
|
// match_get: async {
|
||||||
let s = sp.await.map_err(|e| e.to_string())?.ok_or("Failed to get \"haha yes\"".to_owned())?;
|
// let p = RIOT_API.match_v4().get_match(Region::NA, 3190191338);
|
||||||
let mp = RIOT_API.match_v4().get_matchlist(Region::NA, &s.account_id, None, Some(2500), None, None, Some(2600), None, None);
|
// let m = p.await.map_err(|e| e.to_string())?.ok_or("Match not found.".to_owned())?;
|
||||||
let m = mp.await.map_err(|e| e.to_string())?.ok_or("Failed to get matchlist".to_owned())?;
|
// rassert!(!m.participants.is_empty(), "Match should have participants.");
|
||||||
rassert!(m.matches.len() > 0, "Matchlist should not be empty");
|
// Ok(())
|
||||||
Ok(())
|
// },
|
||||||
},
|
// match_get_bots: async {
|
||||||
|
// let p = RIOT_API.match_v4().get_match(Region::NA, 3251803350);
|
||||||
|
// let m = p.await.map_err(|e| e.to_string())?.ok_or("Match not found.".to_owned())?;
|
||||||
|
// rassert!(!m.participants.is_empty(), "Match should have participants.");
|
||||||
|
// Ok(())
|
||||||
|
// },
|
||||||
|
// match_get_odyssey: async {
|
||||||
|
// let p = RIOT_API.match_v4().get_match(Region::NA, 2881976826);
|
||||||
|
// let m = p.await.map_err(|e| e.to_string())?.ok_or("Match not found.".to_owned())?;
|
||||||
|
// rassert!(!m.participants.is_empty(), "Match should have participants.");
|
||||||
|
// Ok(())
|
||||||
|
// },
|
||||||
|
// match_get_aram: async {
|
||||||
|
// let p = RIOT_API.match_v4().get_match(Region::NA, 2961635718);
|
||||||
|
// let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?;
|
||||||
|
// rassert!(!m.participants.is_empty(), "Match should have participants.");
|
||||||
|
// Ok(())
|
||||||
|
// },
|
||||||
|
// match_get_aram2: async {
|
||||||
|
// let p = RIOT_API.match_v4().get_match(Region::NA, 3596184782);
|
||||||
|
// let m = p.await.map_err(|e| e.to_string())?.ok_or("Match not found.".to_owned())?;
|
||||||
|
// rassert!(!m.participants.is_empty(), "Match should have participants.");
|
||||||
|
// Ok(())
|
||||||
|
// },
|
||||||
|
// match_get_urf900: async {
|
||||||
|
// let p = RIOT_API.match_v4().get_match(Region::NA, 2963663381);
|
||||||
|
// let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?;
|
||||||
|
// rassert!(!m.participants.is_empty(), "Match should have participants.");
|
||||||
|
// Ok(())
|
||||||
|
// },
|
||||||
|
// match_get_tutorial1: async {
|
||||||
|
// let p = RIOT_API.match_v4().get_match(Region::NA, 3432145099);
|
||||||
|
// let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?;
|
||||||
|
// rassert!(!m.participants.is_empty(), "Match should have participants.");
|
||||||
|
// Ok(())
|
||||||
|
// },
|
||||||
|
// match_get_tutorial2: async {
|
||||||
|
// let p = RIOT_API.match_v4().get_match(Region::NA, 3432116214);
|
||||||
|
// let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?;
|
||||||
|
// rassert!(!m.participants.is_empty(), "Match should have participants.");
|
||||||
|
// Ok(())
|
||||||
|
// },
|
||||||
|
// match_get_tutorial3: async {
|
||||||
|
// let p = RIOT_API.match_v4().get_match(Region::NA, 3432156790);
|
||||||
|
// let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?;
|
||||||
|
// rassert!(!m.participants.is_empty(), "Match should have participants.");
|
||||||
|
// Ok(())
|
||||||
|
// },
|
||||||
|
|
||||||
|
// match_gettimeline: async {
|
||||||
|
// let p = RIOT_API.match_v4().get_match_timeline(Region::NA, 3190191338);
|
||||||
|
// let m = p.await.map_err(|e| e.to_string())?.ok_or("Match timeline not found.".to_owned())?;
|
||||||
|
// rassert!(!m.frames.is_empty(), "Match timeline should have frames.");
|
||||||
|
// Ok(())
|
||||||
|
// },
|
||||||
|
|
||||||
match_get: async {
|
|
||||||
let p = RIOT_API.match_v4().get_match(Region::NA, 3190191338);
|
|
||||||
let m = p.await.map_err(|e| e.to_string())?.ok_or("Match not found.".to_owned())?;
|
|
||||||
rassert!(!m.participants.is_empty(), "Match should have participants.");
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
match_get_bots: async {
|
|
||||||
let p = RIOT_API.match_v4().get_match(Region::NA, 3251803350);
|
|
||||||
let m = p.await.map_err(|e| e.to_string())?.ok_or("Match not found.".to_owned())?;
|
|
||||||
rassert!(!m.participants.is_empty(), "Match should have participants.");
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
match_get_odyssey: async {
|
|
||||||
let p = RIOT_API.match_v4().get_match(Region::NA, 2881976826);
|
|
||||||
let m = p.await.map_err(|e| e.to_string())?.ok_or("Match not found.".to_owned())?;
|
|
||||||
rassert!(!m.participants.is_empty(), "Match should have participants.");
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
match_get_aram: async {
|
|
||||||
let p = RIOT_API.match_v4().get_match(Region::NA, 2961635718);
|
|
||||||
let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?;
|
|
||||||
rassert!(!m.participants.is_empty(), "Match should have participants.");
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
match_get_aram2: async {
|
|
||||||
let p = RIOT_API.match_v4().get_match(Region::NA, 3596184782);
|
|
||||||
let m = p.await.map_err(|e| e.to_string())?.ok_or("Match not found.".to_owned())?;
|
|
||||||
rassert!(!m.participants.is_empty(), "Match should have participants.");
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
match_get_urf900: async {
|
|
||||||
let p = RIOT_API.match_v4().get_match(Region::NA, 2963663381);
|
|
||||||
let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?;
|
|
||||||
rassert!(!m.participants.is_empty(), "Match should have participants.");
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
match_get_tutorial1: async {
|
|
||||||
let p = RIOT_API.match_v4().get_match(Region::NA, 3432145099);
|
|
||||||
let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?;
|
|
||||||
rassert!(!m.participants.is_empty(), "Match should have participants.");
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
match_get_tutorial2: async {
|
|
||||||
let p = RIOT_API.match_v4().get_match(Region::NA, 3432116214);
|
|
||||||
let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?;
|
|
||||||
rassert!(!m.participants.is_empty(), "Match should have participants.");
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
match_get_tutorial3: async {
|
|
||||||
let p = RIOT_API.match_v4().get_match(Region::NA, 3432156790);
|
|
||||||
let m = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get match.".to_owned())?;
|
|
||||||
rassert!(!m.participants.is_empty(), "Match should have participants.");
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
|
|
||||||
match_gettimeline: async {
|
|
||||||
let p = RIOT_API.match_v4().get_match_timeline(Region::NA, 3190191338);
|
|
||||||
let m = p.await.map_err(|e| e.to_string())?.ok_or("Match timeline not found.".to_owned())?;
|
|
||||||
rassert!(!m.frames.is_empty(), "Match timeline should have frames.");
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
// Commented out, requires special API key.
|
// Commented out, requires special API key.
|
||||||
// // LOR
|
// // LOR
|
||||||
// lor_ranked_get_leaderboards: async {
|
// lor_ranked_get_leaderboards: async {
|
||||||
|
|
Loading…
Reference in New Issue