Update return Option only if x-nullable-404

This commit is contained in:
Mingwei Samuel 2019-11-07 16:06:01 -08:00
parent 69f7de55f3
commit 8c2cf64784
9 changed files with 101 additions and 79 deletions

View file

@ -38,7 +38,7 @@ rt.block_on(async {
let summoner = riot_api.summoner_v4()
.get_by_summoner_name(Region::NA, "잘못").await
.expect("Get summoner failed.")
.expect("Summoner not found.");
.expect("There is no summoner with that name.");
// Print summoner name.
println!("{} Champion Masteries:", summoner.name);
@ -46,8 +46,7 @@ rt.block_on(async {
// 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.")
.unwrap();
.expect("Get champion masteries failed.");
// Print champioon masteries.
for (i, mastery) in masteries[..10].iter().enumerate() {

View file

@ -137,7 +137,7 @@ impl<'a> ChampionMasteryV4<'a> {
/// * `region` - Region to query.
/// * `encryptedSummonerId` - Summoner ID associated with the player
pub fn get_all_champion_masteries(&self, region: Region, encrypted_summoner_id: &str)
-> impl Future<Output = Result<Option<Vec<champion_mastery_v4::ChampionMastery>>>> + 'a
-> impl Future<Output = Result<Vec<champion_mastery_v4::ChampionMastery>>> + 'a
{
let path_string = format!("/lol/champion-mastery/v4/champion-masteries/by-summoner/{}", encrypted_summoner_id);
self.base.get::<Vec<champion_mastery_v4::ChampionMastery>>("champion-mastery-v4.getAllChampionMasteries", region.into(), path_string, None)
@ -154,7 +154,7 @@ impl<'a> ChampionMasteryV4<'a> {
-> impl Future<Output = Result<Option<champion_mastery_v4::ChampionMastery>>> + 'a
{
let path_string = format!("/lol/champion-mastery/v4/champion-masteries/by-summoner/{}/by-champion/{}", encrypted_summoner_id, champion_id);
self.base.get::<champion_mastery_v4::ChampionMastery>("champion-mastery-v4.getChampionMastery", region.into(), path_string, None)
self.base.get_optional::<champion_mastery_v4::ChampionMastery>("champion-mastery-v4.getChampionMastery", region.into(), path_string, None)
}
/// Get a player's total champion mastery score, which is the sum of individual champion mastery levels.
@ -164,7 +164,7 @@ impl<'a> ChampionMasteryV4<'a> {
/// * `region` - Region to query.
/// * `encryptedSummonerId` - Summoner ID associated with the player
pub fn get_champion_mastery_score(&self, region: Region, encrypted_summoner_id: &str)
-> impl Future<Output = Result<Option<i32>>> + 'a
-> impl Future<Output = Result<i32>> + 'a
{
let path_string = format!("/lol/champion-mastery/v4/scores/by-summoner/{}", encrypted_summoner_id);
self.base.get::<i32>("champion-mastery-v4.getChampionMasteryScore", region.into(), path_string, None)
@ -185,7 +185,7 @@ impl<'a> ChampionV3<'a> {
/// # Parameters
/// * `region` - Region to query.
pub fn get_champion_info(&self, region: Region)
-> impl Future<Output = Result<Option<champion_v3::ChampionInfo>>> + 'a
-> impl Future<Output = Result<champion_v3::ChampionInfo>> + 'a
{
let path_string = "/lol/platform/v3/champion-rotations".to_owned();
self.base.get::<champion_v3::ChampionInfo>("champion-v3.getChampionInfo", region.into(), path_string, None)
@ -210,7 +210,7 @@ impl<'a> LeagueExpV4<'a> {
/// * `division`
/// * `page` (optional) - Starts with page 1.
pub fn get_league_entries(&self, region: Region, queue: crate::consts::QueueType, tier: crate::consts::Tier, division: crate::consts::Division, page: Option<i32>)
-> impl Future<Output = Result<Option<Vec<league_exp_v4::LeagueEntry>>>> + 'a
-> impl Future<Output = Result<Vec<league_exp_v4::LeagueEntry>>> + 'a
{
let mut query_params = Serializer::new(String::new());
if let Some(page) = page { query_params.append_pair("page", &*page.to_string()); };
@ -235,7 +235,7 @@ impl<'a> LeagueV4<'a> {
/// * `region` - Region to query.
/// * `queue`
pub fn get_challenger_league(&self, region: Region, queue: crate::consts::QueueType)
-> impl Future<Output = Result<Option<league_v4::LeagueList>>> + 'a
-> impl Future<Output = Result<league_v4::LeagueList>> + 'a
{
let path_string = format!("/lol/league/v4/challengerleagues/by-queue/{}", queue);
self.base.get::<league_v4::LeagueList>("league-v4.getChallengerLeague", region.into(), path_string, None)
@ -248,7 +248,7 @@ impl<'a> LeagueV4<'a> {
/// * `region` - Region to query.
/// * `encryptedSummonerId`
pub fn get_league_entries_for_summoner(&self, region: Region, encrypted_summoner_id: &str)
-> impl Future<Output = Result<Option<Vec<league_v4::LeagueEntry>>>> + 'a
-> impl Future<Output = Result<Vec<league_v4::LeagueEntry>>> + 'a
{
let path_string = format!("/lol/league/v4/entries/by-summoner/{}", encrypted_summoner_id);
self.base.get::<Vec<league_v4::LeagueEntry>>("league-v4.getLeagueEntriesForSummoner", region.into(), path_string, None)
@ -264,7 +264,7 @@ impl<'a> LeagueV4<'a> {
/// * `queue` - Note that the queue value must be a valid ranked queue.
/// * `page` (optional) - Starts with page 1.
pub fn get_league_entries(&self, region: Region, queue: crate::consts::QueueType, tier: crate::consts::Tier, division: crate::consts::Division, page: Option<i32>)
-> impl Future<Output = Result<Option<Vec<league_v4::LeagueEntry>>>> + 'a
-> impl Future<Output = Result<Vec<league_v4::LeagueEntry>>> + 'a
{
let mut query_params = Serializer::new(String::new());
if let Some(page) = page { query_params.append_pair("page", &*page.to_string()); };
@ -280,7 +280,7 @@ impl<'a> LeagueV4<'a> {
/// * `region` - Region to query.
/// * `queue`
pub fn get_grandmaster_league(&self, region: Region, queue: crate::consts::QueueType)
-> impl Future<Output = Result<Option<league_v4::LeagueList>>> + 'a
-> impl Future<Output = Result<league_v4::LeagueList>> + 'a
{
let path_string = format!("/lol/league/v4/grandmasterleagues/by-queue/{}", queue);
self.base.get::<league_v4::LeagueList>("league-v4.getGrandmasterLeague", region.into(), path_string, None)
@ -296,7 +296,7 @@ impl<'a> LeagueV4<'a> {
-> impl Future<Output = Result<Option<league_v4::LeagueList>>> + 'a
{
let path_string = format!("/lol/league/v4/leagues/{}", league_id);
self.base.get::<league_v4::LeagueList>("league-v4.getLeagueById", region.into(), path_string, None)
self.base.get_optional::<league_v4::LeagueList>("league-v4.getLeagueById", region.into(), path_string, None)
}
/// Get the master league for given queue.
@ -306,7 +306,7 @@ impl<'a> LeagueV4<'a> {
/// * `region` - Region to query.
/// * `queue`
pub fn get_master_league(&self, region: Region, queue: crate::consts::QueueType)
-> impl Future<Output = Result<Option<league_v4::LeagueList>>> + 'a
-> impl Future<Output = Result<league_v4::LeagueList>> + 'a
{
let path_string = format!("/lol/league/v4/masterleagues/by-queue/{}", queue);
self.base.get::<league_v4::LeagueList>("league-v4.getMasterLeague", region.into(), path_string, None)
@ -329,7 +329,7 @@ impl<'a> LolStatusV3<'a> {
/// # Parameters
/// * `region` - Region to query.
pub fn get_shard_data(&self, region: Region)
-> impl Future<Output = Result<Option<lol_status_v3::ShardStatus>>> + 'a
-> impl Future<Output = Result<lol_status_v3::ShardStatus>> + 'a
{
let path_string = "/lol/status/v3/shard-data".to_owned();
self.base.get::<lol_status_v3::ShardStatus>("lol-status-v3.getShardData", region.into(), path_string, None)
@ -351,7 +351,7 @@ impl<'a> MatchV4<'a> {
/// * `region` - Region to query.
/// * `tournamentCode` - The tournament code.
pub fn get_match_ids_by_tournament_code(&self, region: Region, tournament_code: &str)
-> impl Future<Output = Result<Option<Vec<i64>>>> + 'a
-> 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)
@ -367,7 +367,7 @@ impl<'a> MatchV4<'a> {
-> impl Future<Output = Result<Option<match_v4::Match>>> + 'a
{
let path_string = format!("/lol/match/v4/matches/{}", match_id);
self.base.get::<match_v4::Match>("match-v4.getMatch", region.into(), path_string, None)
self.base.get_optional::<match_v4::Match>("match-v4.getMatch", region.into(), path_string, None)
}
/// Get match by match ID and tournament code.
@ -378,7 +378,7 @@ impl<'a> MatchV4<'a> {
/// * `tournamentCode` - The tournament code.
/// * `matchId` - The match ID.
pub fn get_match_by_tournament_code(&self, region: Region, match_id: i64, tournament_code: &str)
-> impl Future<Output = Result<Option<match_v4::Match>>> + 'a
-> 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)
@ -416,7 +416,7 @@ impl<'a> MatchV4<'a> {
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::<match_v4::Matchlist>("match-v4.getMatchlist", region.into(), path_string, Some(query_string))
self.base.get_optional::<match_v4::Matchlist>("match-v4.getMatchlist", region.into(), path_string, Some(query_string))
}
/// Get match timeline by match ID.
@ -431,7 +431,7 @@ impl<'a> MatchV4<'a> {
-> impl Future<Output = Result<Option<match_v4::MatchTimeline>>> + 'a
{
let path_string = format!("/lol/match/v4/timelines/by-match/{}", match_id);
self.base.get::<match_v4::MatchTimeline>("match-v4.getMatchTimeline", region.into(), path_string, None)
self.base.get_optional::<match_v4::MatchTimeline>("match-v4.getMatchTimeline", region.into(), path_string, None)
}
}
@ -453,7 +453,7 @@ impl<'a> SpectatorV4<'a> {
-> impl Future<Output = Result<Option<spectator_v4::CurrentGameInfo>>> + 'a
{
let path_string = format!("/lol/spectator/v4/active-games/by-summoner/{}", encrypted_summoner_id);
self.base.get::<spectator_v4::CurrentGameInfo>("spectator-v4.getCurrentGameInfoBySummoner", region.into(), path_string, None)
self.base.get_optional::<spectator_v4::CurrentGameInfo>("spectator-v4.getCurrentGameInfoBySummoner", region.into(), path_string, None)
}
/// Get list of featured games.
@ -462,7 +462,7 @@ impl<'a> SpectatorV4<'a> {
/// # Parameters
/// * `region` - Region to query.
pub fn get_featured_games(&self, region: Region)
-> impl Future<Output = Result<Option<spectator_v4::FeaturedGames>>> + 'a
-> impl Future<Output = Result<spectator_v4::FeaturedGames>> + 'a
{
let path_string = "/lol/spectator/v4/featured-games".to_owned();
self.base.get::<spectator_v4::FeaturedGames>("spectator-v4.getFeaturedGames", region.into(), path_string, None)
@ -484,7 +484,7 @@ impl<'a> SummonerV4<'a> {
/// * `region` - Region to query.
/// * `encryptedAccountId`
pub fn get_by_account_id(&self, region: Region, encrypted_account_id: &str)
-> impl Future<Output = Result<Option<summoner_v4::Summoner>>> + 'a
-> impl Future<Output = Result<summoner_v4::Summoner>> + 'a
{
let path_string = format!("/lol/summoner/v4/summoners/by-account/{}", encrypted_account_id);
self.base.get::<summoner_v4::Summoner>("summoner-v4.getByAccountId", region.into(), path_string, None)
@ -500,7 +500,7 @@ impl<'a> SummonerV4<'a> {
-> impl Future<Output = Result<Option<summoner_v4::Summoner>>> + 'a
{
let path_string = format!("/lol/summoner/v4/summoners/by-name/{}", summoner_name);
self.base.get::<summoner_v4::Summoner>("summoner-v4.getBySummonerName", region.into(), path_string, None)
self.base.get_optional::<summoner_v4::Summoner>("summoner-v4.getBySummonerName", region.into(), path_string, None)
}
/// Get a summoner by PUUID.
@ -510,7 +510,7 @@ impl<'a> SummonerV4<'a> {
/// * `region` - Region to query.
/// * `encryptedPUUID` - Summoner ID
pub fn get_by_puuid(&self, region: Region, encrypted_puuid: &str)
-> impl Future<Output = Result<Option<summoner_v4::Summoner>>> + 'a
-> impl Future<Output = Result<summoner_v4::Summoner>> + 'a
{
let path_string = format!("/lol/summoner/v4/summoners/by-puuid/{}", encrypted_puuid);
self.base.get::<summoner_v4::Summoner>("summoner-v4.getByPUUID", region.into(), path_string, None)
@ -523,7 +523,7 @@ impl<'a> SummonerV4<'a> {
/// * `region` - Region to query.
/// * `encryptedSummonerId` - Summoner ID
pub fn get_by_summoner_id(&self, region: Region, encrypted_summoner_id: &str)
-> impl Future<Output = Result<Option<summoner_v4::Summoner>>> + 'a
-> impl Future<Output = Result<summoner_v4::Summoner>> + 'a
{
let path_string = format!("/lol/summoner/v4/summoners/{}", encrypted_summoner_id);
self.base.get::<summoner_v4::Summoner>("summoner-v4.getBySummonerId", region.into(), path_string, None)
@ -544,7 +544,7 @@ impl<'a> TftLeagueV1<'a> {
/// # Parameters
/// * `region` - Region to query.
pub fn get_challenger_league(&self, region: Region)
-> impl Future<Output = Result<Option<tft_league_v1::LeagueList>>> + 'a
-> impl Future<Output = Result<tft_league_v1::LeagueList>> + 'a
{
let path_string = "/tft/league/v1/challenger".to_owned();
self.base.get::<tft_league_v1::LeagueList>("tft-league-v1.getChallengerLeague", region.into(), path_string, None)
@ -557,7 +557,7 @@ impl<'a> TftLeagueV1<'a> {
/// * `region` - Region to query.
/// * `encryptedSummonerId`
pub fn get_league_entries_for_summoner(&self, region: Region, encrypted_summoner_id: &str)
-> impl Future<Output = Result<Option<Vec<tft_league_v1::LeagueEntry>>>> + 'a
-> impl Future<Output = Result<Vec<tft_league_v1::LeagueEntry>>> + 'a
{
let path_string = format!("/tft/league/v1/entries/by-summoner/{}", encrypted_summoner_id);
self.base.get::<Vec<tft_league_v1::LeagueEntry>>("tft-league-v1.getLeagueEntriesForSummoner", region.into(), path_string, None)
@ -572,7 +572,7 @@ impl<'a> TftLeagueV1<'a> {
/// * `division`
/// * `page` (optional) - Starts with page 1.
pub fn get_league_entries(&self, region: Region, tier: &str, division: &str, page: Option<i32>)
-> impl Future<Output = Result<Option<Vec<tft_league_v1::LeagueEntry>>>> + 'a
-> impl Future<Output = Result<Vec<tft_league_v1::LeagueEntry>>> + 'a
{
let mut query_params = Serializer::new(String::new());
if let Some(page) = page { query_params.append_pair("page", &*page.to_string()); };
@ -587,7 +587,7 @@ impl<'a> TftLeagueV1<'a> {
/// # Parameters
/// * `region` - Region to query.
pub fn get_grandmaster_league(&self, region: Region)
-> impl Future<Output = Result<Option<tft_league_v1::LeagueList>>> + 'a
-> impl Future<Output = Result<tft_league_v1::LeagueList>> + 'a
{
let path_string = "/tft/league/v1/grandmaster".to_owned();
self.base.get::<tft_league_v1::LeagueList>("tft-league-v1.getGrandmasterLeague", region.into(), path_string, None)
@ -600,7 +600,7 @@ impl<'a> TftLeagueV1<'a> {
/// * `region` - Region to query.
/// * `leagueId` - The UUID of the league.
pub fn get_league_by_id(&self, region: Region, league_id: &str)
-> impl Future<Output = Result<Option<tft_league_v1::LeagueList>>> + 'a
-> impl Future<Output = Result<tft_league_v1::LeagueList>> + 'a
{
let path_string = format!("/tft/league/v1/leagues/{}", league_id);
self.base.get::<tft_league_v1::LeagueList>("tft-league-v1.getLeagueById", region.into(), path_string, None)
@ -612,7 +612,7 @@ impl<'a> TftLeagueV1<'a> {
/// # Parameters
/// * `region` - Region to query.
pub fn get_master_league(&self, region: Region)
-> impl Future<Output = Result<Option<tft_league_v1::LeagueList>>> + 'a
-> impl Future<Output = Result<tft_league_v1::LeagueList>> + 'a
{
let path_string = "/tft/league/v1/master".to_owned();
self.base.get::<tft_league_v1::LeagueList>("tft-league-v1.getMasterLeague", region.into(), path_string, None)
@ -634,7 +634,7 @@ impl<'a> TftMatchV1<'a> {
/// * `region` - Region to query.
/// * `encryptedPUUID` (optional)
pub fn get_match_ids_by_puuid(&self, region: Region, encrypted_puuid: &str)
-> impl Future<Output = Result<Option<Vec<String>>>> + 'a
-> impl Future<Output = Result<Vec<String>>> + 'a
{
let path_string = format!("/tft/match/v1/matches/by-puuid/{}/ids", encrypted_puuid);
self.base.get::<Vec<String>>("tft-match-v1.getMatchIdsByPUUID", region.into(), path_string, None)
@ -647,7 +647,7 @@ impl<'a> TftMatchV1<'a> {
/// * `region` - Region to query.
/// * `matchId`
pub fn get_match(&self, region: Region, match_id: &str)
-> impl Future<Output = Result<Option<tft_match_v1::Match>>> + 'a
-> impl Future<Output = Result<tft_match_v1::Match>> + 'a
{
let path_string = format!("/tft/match/v1/matches/{}", match_id);
self.base.get::<tft_match_v1::Match>("tft-match-v1.getMatch", region.into(), path_string, None)
@ -669,7 +669,7 @@ impl<'a> TftSummonerV1<'a> {
/// * `region` - Region to query.
/// * `encryptedAccountId`
pub fn get_by_account_id(&self, region: Region, encrypted_account_id: &str)
-> impl Future<Output = Result<Option<tft_summoner_v1::Summoner>>> + 'a
-> impl Future<Output = Result<tft_summoner_v1::Summoner>> + 'a
{
let path_string = format!("/tft/summoner/v1/summoners/by-account/{}", encrypted_account_id);
self.base.get::<tft_summoner_v1::Summoner>("tft-summoner-v1.getByAccountId", region.into(), path_string, None)
@ -682,7 +682,7 @@ impl<'a> TftSummonerV1<'a> {
/// * `region` - Region to query.
/// * `summonerName` - Summoner Name
pub fn get_by_summoner_name(&self, region: Region, summoner_name: &str)
-> impl Future<Output = Result<Option<tft_summoner_v1::Summoner>>> + 'a
-> impl Future<Output = Result<tft_summoner_v1::Summoner>> + 'a
{
let path_string = format!("/tft/summoner/v1/summoners/by-name/{}", summoner_name);
self.base.get::<tft_summoner_v1::Summoner>("tft-summoner-v1.getBySummonerName", region.into(), path_string, None)
@ -695,7 +695,7 @@ impl<'a> TftSummonerV1<'a> {
/// * `region` - Region to query.
/// * `encryptedPUUID` - Summoner ID
pub fn get_by_puuid(&self, region: Region, encrypted_puuid: &str)
-> impl Future<Output = Result<Option<tft_summoner_v1::Summoner>>> + 'a
-> impl Future<Output = Result<tft_summoner_v1::Summoner>> + 'a
{
let path_string = format!("/tft/summoner/v1/summoners/by-puuid/{}", encrypted_puuid);
self.base.get::<tft_summoner_v1::Summoner>("tft-summoner-v1.getByPUUID", region.into(), path_string, None)
@ -708,7 +708,7 @@ impl<'a> TftSummonerV1<'a> {
/// * `region` - Region to query.
/// * `encryptedSummonerId` - Summoner ID
pub fn get_by_summoner_id(&self, region: Region, encrypted_summoner_id: &str)
-> impl Future<Output = Result<Option<tft_summoner_v1::Summoner>>> + 'a
-> impl Future<Output = Result<tft_summoner_v1::Summoner>> + 'a
{
let path_string = format!("/tft/summoner/v1/summoners/{}", encrypted_summoner_id);
self.base.get::<tft_summoner_v1::Summoner>("tft-summoner-v1.getBySummonerId", region.into(), path_string, None)
@ -730,7 +730,7 @@ impl<'a> ThirdPartyCodeV4<'a> {
/// * `region` - Region to query.
/// * `encryptedSummonerId`
pub fn get_third_party_code_by_summoner_id(&self, region: Region, encrypted_summoner_id: &str)
-> impl Future<Output = Result<Option<String>>> + 'a
-> impl Future<Output = Result<String>> + 'a
{
let path_string = format!("/lol/platform/v4/third-party-code/by-summoner/{}", encrypted_summoner_id);
self.base.get::<String>("third-party-code-v4.getThirdPartyCodeBySummonerId", region.into(), path_string, None)
@ -752,7 +752,7 @@ impl<'a> TournamentStubV4<'a> {
/// * `region` - Region to query.
/// * `tournamentCode` - The short code to look up lobby events for
pub fn get_lobby_events_by_code(&self, region: Region, tournament_code: &str)
-> impl Future<Output = Result<Option<tournament_stub_v4::LobbyEventWrapper>>> + 'a
-> impl Future<Output = Result<tournament_stub_v4::LobbyEventWrapper>> + 'a
{
let path_string = format!("/lol/tournament-stub/v4/lobby-events/by-code/{}", tournament_code);
self.base.get::<tournament_stub_v4::LobbyEventWrapper>("tournament-stub-v4.getLobbyEventsByCode", region.into(), path_string, None)
@ -774,7 +774,7 @@ impl<'a> TournamentV4<'a> {
/// * `region` - Region to query.
/// * `tournamentCode` - The tournament code string.
pub fn get_tournament_code(&self, region: Region, tournament_code: &str)
-> impl Future<Output = Result<Option<tournament_v4::TournamentCode>>> + 'a
-> impl Future<Output = Result<tournament_v4::TournamentCode>> + 'a
{
let path_string = format!("/lol/tournament/v4/codes/{}", tournament_code);
self.base.get::<tournament_v4::TournamentCode>("tournament-v4.getTournamentCode", region.into(), path_string, None)
@ -787,7 +787,7 @@ impl<'a> TournamentV4<'a> {
/// * `region` - Region to query.
/// * `tournamentCode` - The short code to look up lobby events for
pub fn get_lobby_events_by_code(&self, region: Region, tournament_code: &str)
-> impl Future<Output = Result<Option<tournament_v4::LobbyEventWrapper>>> + 'a
-> impl Future<Output = Result<tournament_v4::LobbyEventWrapper>> + 'a
{
let path_string = format!("/lol/tournament/v4/lobby-events/by-code/{}", tournament_code);
self.base.get::<tournament_v4::LobbyEventWrapper>("tournament-v4.getLobbyEventsByCode", region.into(), path_string, None)

View file

@ -37,7 +37,8 @@ impl RiotApiError {
pub fn retries(&self) -> u8 {
self.retries
}
/// The failed response, if the request sent.
/// The failed response, if the request was sent and failed.
/// Will be `None` if JSON parsing failed.
pub fn response<'a>(&self) -> Option<&Response> {
self.response.as_ref()
}

View file

@ -24,8 +24,8 @@ impl RegionalRequester {
/// Request header name for the Riot API key.
const RIOT_KEY_HEADER: &'static str = "X-Riot-Token";
/// HttpStatus codes that are considered a success, but will return None.
const NONE_STATUS_CODES: [u16; 3] = [ 204, 404, 422 ];
/// Http status code 404, considered a success but will return None.
const NONE_STATUS_CODE: StatusCode = StatusCode::NOT_FOUND;
pub fn new() -> Self {
@ -35,10 +35,29 @@ impl RegionalRequester {
}
}
pub fn get<'a, T: serde::de::DeserializeOwned>(self: Arc<Self>,
pub fn get_optional<'a, T: serde::de::DeserializeOwned>(self: Arc<Self>,
config: &'a RiotApiConfig, client: &'a Client,
method_id: &'static str, region_platform: &'a str, path: String, query: Option<String>)
-> impl Future<Output = Result<Option<T>>> + 'a
{
async move {
let response_result = self.get(config, client,
method_id, region_platform, path, query).await;
response_result.map(|value| Some(value))
.or_else(|e| {
if let Some(response) = e.response() {
if Self::NONE_STATUS_CODE == response.status() {
return Ok(None);
}}
Err(e)
})
}
}
pub fn get<'a, T: serde::de::DeserializeOwned>(self: Arc<Self>,
config: &'a RiotApiConfig, client: &'a Client,
method_id: &'static str, region_platform: &'a str, path: String, query: Option<String>)
-> impl Future<Output = Result<T>> + 'a
{
async move {
#[cfg(feature = "nightly")] let query = query.as_deref();
@ -71,21 +90,14 @@ impl RegionalRequester {
self.app_rate_limit.on_response(&config, &response);
method_rate_limit.on_response(&config, &response);
// Handle response.
let status = response.status();
// Special "none success" cases, return None.
if Self::is_none_status_code(&status) {
log::trace!("Response {} (retried {} times), None result.", status, retries);
break Ok(None);
}
// Handle normal success / failure cases.
match response.error_for_status_ref() {
// Success.
Ok(_) => {
Ok(_response) => {
log::trace!("Response {} (retried {} times), parsed result.", status, retries);
let value = response.json::<T>().await;
break value.map(|v| Some(v))
.map_err(|e| RiotApiError::new(e, retries, None));
break value.map_err(|e| RiotApiError::new(e, retries, None));
},
// Failure, may or may not be retryable.
Err(err) => {
@ -95,7 +107,7 @@ impl RegionalRequester {
(StatusCode::TOO_MANY_REQUESTS != status
&& !status.is_server_error())
{
log::debug!("Response {} (retried {} times), returning error.", status, retries);
log::debug!("Response {} (retried {} times), returning.", status, retries);
break Err(RiotApiError::new(err, retries, Some(response)));
}
log::debug!("Response {} (retried {} times), retrying.", status, retries);
@ -106,10 +118,6 @@ impl RegionalRequester {
}
}
}
fn is_none_status_code(status: &StatusCode) -> bool {
Self::NONE_STATUS_CODES.contains(&status.as_u16())
}
}
#[cfg(test)]

View file

@ -1,4 +1,5 @@
use std::future::Future;
use std::sync::Arc;
use log;
use reqwest::Client;
@ -12,7 +13,7 @@ use crate::util::InsertOnlyCHashMap;
///
/// # Rate Limiting
///
/// The Riot Game API does _dynamic_ rate limiting, meaning that rate limits are
/// The Riot Game API enforces _dynamic_ rate limiting, meaning that rate limits are
/// specified in response headers and (hypothetically) could change at any time.
/// Riven keeps track of changing rate limits seamlessly, preventing you from
/// getting blacklisted.
@ -44,15 +45,26 @@ impl RiotApi {
Self::with_config(RiotApiConfig::with_key(api_key))
}
pub fn get<'a, T: serde::de::DeserializeOwned + 'a>(&'a self,
pub fn get_optional<'a, T: serde::de::DeserializeOwned + 'a>(&'a self,
method_id: &'static str, region_platform: &'static str, path: String, query: Option<String>)
-> impl Future<Output = Result<Option<T>>> + 'a
{
self.regional_requesters
.get_or_insert_with(region_platform, || {
log::debug!("Creating requester for region platform {}.", region_platform);
RegionalRequester::new()
})
self.regional_requester(region_platform)
.get_optional(&self.config, &self.client, method_id, region_platform, path, query)
}
pub fn get<'a, T: serde::de::DeserializeOwned + 'a>(&'a self,
method_id: &'static str, region_platform: &'static str, path: String, query: Option<String>)
-> impl Future<Output = Result<T>> + 'a
{
self.regional_requester(region_platform)
.get(&self.config, &self.client, method_id, region_platform, path, query)
}
fn regional_requester(&self, region_platform: &'static str) -> Arc<RegionalRequester> {
self.regional_requesters.get_or_insert_with(region_platform, || {
log::debug!("Creating requester for region platform {}.", region_platform);
RegionalRequester::new()
})
}
}

View file

@ -66,7 +66,10 @@ impl<'a> {{= endpoint }}<'a> {
let method = dotUtils.changeCase.snakeCase(operationId.slice(operationId.indexOf('.') + 1));
let jsonInfo = get.responses['200'].content['application/json'];
let returnType = dotUtils.stringifyType(jsonInfo.schema, { endpoint, fullpath: false });
let returnOptional = !!get['x-nullable-404'];
let parseType = dotUtils.stringifyType(jsonInfo.schema, { endpoint, fullpath: false });
let returnType = returnOptional ? `Option<${parseType}>` : parseType;
/* Cases if not rate limited. */
let rateLimitExcluded = get['x-app-rate-limit-excluded'] ? true : false;
@ -131,7 +134,7 @@ impl<'a> {{= endpoint }}<'a> {
}
}}
pub fn {{= method }}(&self, region: Region{{= argBuilder.join('') }})
-> impl Future<Output = Result<Option<{{= returnType }}>>> + 'a
-> impl Future<Output = Result<{{= returnType }}>> + 'a
{
{{? queryParams.length }}
let mut query_params = Serializer::new(String::new());
@ -146,7 +149,7 @@ impl<'a> {{= endpoint }}<'a> {
let query_string = query_params.finish();
{{?}}
let path_string = {{= routeArgument }};
self.base.get::<{{= returnType }}>("{{= operationId }}", region.into(), path_string, {{= queryParams.length ? 'Some(query_string)' : 'None' }})
self.base.get{{= returnOptional ? '_optional' : '' }}::<{{= parseType }}>("{{= operationId }}", region.into(), path_string, {{= queryParams.length ? 'Some(query_string)' : 'None' }})
}
{{

View file

@ -15,20 +15,20 @@ async_tests!{
// Champion Mastery tests.
championmastery_getscore_ma5tery: async {
let p = RIOT_API.champion_mastery_v4().get_champion_mastery_score(Region::EUW, ids::SUMMONER_ID_MA5TERY);
let s = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get ma5tery".to_owned())?;
let s = p.await.map_err(|e| e.to_string())?;
rassert!(969 <= s && s <= 1000, "Unexpected ma5tery score: {}.", s);
Ok(())
},
championmastery_getall_ma5tery: async {
let p = RIOT_API.champion_mastery_v4().get_all_champion_masteries(Region::EUW, ids::SUMMONER_ID_MA5TERY);
let s = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get ma5tery".to_owned())?;
let s = p.await.map_err(|e| e.to_string())?;
rassert!(s.len() >= 142, "Expected masteries: {}.", s.len());
Ok(())
},
// // TFT tests.
// tftleaguev1_getchallengerleague: async {
// let p = RIOT_API.tft_league_v1().get_challenger_league(Region::EUW);
// let l = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get TFT Challenger.".to_owned())?;
// let l = p.await.map_err(|e| e.to_string())?;
// rassert!(l.entries.len() > 10, "Expected a few challenger players, got: {}.", l.entries.len());
// Ok(())
// },

View file

@ -35,7 +35,7 @@ async_tests!{
},
champion_getrotation: async {
let p = RIOT_API.champion_v3().get_champion_info(Region::NA);
let d = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get champ info.".to_owned())?;
let d = p.await.map_err(|e| e.to_string())?;
let new_len = d.free_champion_ids_for_new_players.len();
let free_len = d.free_champion_ids.len();
let level = d.max_new_player_level;
@ -46,13 +46,13 @@ async_tests!{
},
leagueexp_get: async {
let p = RIOT_API.league_exp_v4().get_league_entries(Region::NA, QueueType::RANKED_SOLO_5x5, Tier::CHALLENGER, Division::I, None);
let d = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get challenger exp league entries.".to_owned())?;
let d = p.await.map_err(|e| e.to_string())?;
rassert!(!d.is_empty(), "Challenger shouldn't be empty.");
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("Failed to get match.".to_owned())?;
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(())
},

View file

@ -18,7 +18,7 @@ async_tests!{
league_summoner_bulk_test: async {
let p = RIOT_API.league_v4().get_challenger_league(REGION, QueueType::RANKED_SOLO_5x5);
// let p = future_start(p);
let ll = p.await.map_err(|e| e.to_string())?.ok_or("Failed to get challenger league".to_owned())?;
let ll = p.await.map_err(|e| e.to_string())?;
println!("{:?} Challenger {} entries.", REGION, ll.entries.len());
@ -28,8 +28,7 @@ async_tests!{
.collect::<Vec<_>>();
for (i, s) in sl.into_iter().enumerate() {
let summoner_opt: Option<Summoner> = s.await.map_err(|e| e.to_string())?;
let summoner = summoner_opt.ok_or("Failed to get summoner.".to_owned())?;
let summoner: Summoner = s.await.map_err(|e| e.to_string())?;
println!("{}: {}", i + 1, summoner.name);
}