chore: replace `lazy_static` with std `OnceLock`

pull/63/head
Mingwei Samuel 2024-02-24 09:46:11 -08:00
parent 101633bb47
commit 092ea34358
18 changed files with 106 additions and 97 deletions

View File

@ -39,7 +39,6 @@ deny-unknown-enum-variants-strings = []
deny-unknown-enum-variants-integers = []
[dependencies]
lazy_static = "1.4"
log = "0.4"
num_enum = "0.5"
parking_lot = "0.12"

View File

@ -1,28 +1,31 @@
// #![deny(warnings)]
use std::convert::Infallible;
use std::sync::OnceLock;
use http::{Method, Request, Response, StatusCode};
use hyper::header::HeaderValue;
use hyper::service::{make_service_fn, service_fn};
use hyper::{http, Body, Server};
use lazy_static::lazy_static;
use riven::consts::Route;
use riven::{RiotApi, RiotApiConfig};
use tracing as log;
lazy_static! {
/// Create lazy static RiotApi instance.
/// Easier than passing it around.
pub static ref RIOT_API: RiotApi = {
let api_key = std::env::var("RGAPI_KEY").ok()
static RIOT_API: OnceLock<RiotApi> = OnceLock::new();
pub fn riot_api() -> &'static RiotApi {
RIOT_API.get_or_init(|| {
let api_key = std::env::var("RGAPI_KEY")
.ok()
.or_else(|| {
let path: std::path::PathBuf = [ env!("CARGO_MANIFEST_DIR"), "../../apikey.txt" ].iter().collect();
use std::iter::FromIterator;
let path =
std::path::PathBuf::from_iter([env!("CARGO_MANIFEST_DIR"), "../apikey.txt"]);
std::fs::read_to_string(path).ok()
})
.expect("Failed to find RGAPI_KEY env var or apikey.txt.");
RiotApi::new(RiotApiConfig::with_key(api_key.trim()).preconfig_burst())
};
})
}
/// Helper to create JSON error responses.
@ -73,10 +76,12 @@ async fn handle_request(req: Request<Body>) -> Result<Response<Body>, Infallible
Ok(bytes) => bytes,
};
let req_builder = RIOT_API.request(method, route.into(), req_path).body(body);
let req_builder = riot_api()
.request(method, route.into(), req_path)
.body(body);
// Send request to Riot API.
let resp_result = RIOT_API
let resp_result = riot_api()
.execute_raw(method_id, route.into(), req_builder)
.await;
let resp_info = match resp_result {
@ -169,8 +174,8 @@ pub async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// env_logger::init();
tracing_subscriber::fmt::init();
// Trigger lazy_static.
let _ = &*RIOT_API;
// Trigger initialization.
let _ = riot_api();
// For every connection, we must make a `Service` to handle all
// incoming HTTP requests on said connection.

View File

@ -7,18 +7,14 @@ mod token_bucket {
include!("token_bucket.rs");
mod tests {
use lazy_static::lazy_static;
use super::*;
lazy_static! {
pub static ref ZERO: Duration = Duration::new(0, 0);
}
pub const ZERO: Duration = Duration::new(0, 0);
#[test]
fn test_basic() {
Instant::set_time(50_000);
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, *ZERO, 0.95, 1.0);
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, ZERO, 0.95, 1.0);
assert!(bucket.get_tokens(50), "Should have not violated limit.");
assert_eq!(None, bucket.get_delay(), "Can get stuff.");
assert!(!bucket.get_tokens(51), "Should have violated limit.");
@ -26,20 +22,20 @@ mod token_bucket {
#[test]
fn test_internal_constructor() {
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, *ZERO, 1.0, 1.0);
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, ZERO, 1.0, 1.0);
assert_eq!(100, bucket.burst_limit);
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, *ZERO, 1e-6, 1.0);
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, ZERO, 1e-6, 1.0);
assert_eq!(1, bucket.burst_limit);
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, *ZERO, 1.0, 1e-6);
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, ZERO, 1.0, 1e-6);
assert_eq!(1, bucket.total_limit);
assert_eq!(1, bucket.burst_limit);
}
#[test]
fn test_saturated_100_burst() {
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, *ZERO, 1.00, 1.0);
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, ZERO, 1.00, 1.0);
Instant::set_time(50_000);
assert!(
@ -58,7 +54,7 @@ mod token_bucket {
#[test]
fn test_saturated_95_burst() {
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, *ZERO, 0.95, 1.0);
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, ZERO, 0.95, 1.0);
Instant::set_time(50_000);
assert!(
@ -85,7 +81,7 @@ mod token_bucket {
#[test]
fn test_violated_50_burst() {
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, *ZERO, 0.50, 1.0);
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, ZERO, 0.50, 1.0);
Instant::set_time(50_000);
assert!(!bucket.get_tokens(90), "Burst should be violated.");
@ -94,7 +90,7 @@ mod token_bucket {
#[test]
fn test_saturated_50_burst() {
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, *ZERO, 0.50, 1.0);
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, ZERO, 0.50, 1.0);
Instant::set_time(50_000);
assert!(
@ -128,7 +124,7 @@ mod token_bucket {
let bucket = VectorTokenBucket::new(
Duration::from_millis(1000),
100,
*ZERO,
ZERO,
0.90,
rate_usage_factor,
);
@ -159,7 +155,7 @@ mod token_bucket {
#[test]
fn test_many() {
Instant::set_time(50_000);
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, *ZERO, 0.5, 1.0);
let bucket = VectorTokenBucket::new(Duration::from_millis(1000), 100, ZERO, 0.5, 1.0);
assert!(
bucket.get_tokens(50),
"Should have not violated limit. i=-1."

View File

@ -6,7 +6,7 @@ const ROUTE: PlatformRoute = PlatformRoute::RU;
#[tokio_shared_rt::test]
async fn summoner_leagues() -> Result<(), String> {
let sum = RIOT_API
let sum = riot_api()
.summoner_v4()
.get_by_summoner_name(ROUTE, "d3atomiz3d");
let sum = sum
@ -14,7 +14,7 @@ async fn summoner_leagues() -> Result<(), String> {
.map_err(|e| format!("Error getting summoner: {}", e))?
.ok_or_else(|| "Failed to find summoner".to_owned())?;
let p = RIOT_API
let p = riot_api()
.league_v4()
.get_league_entries_for_summoner(ROUTE, &sum.id);
let s = p

View File

@ -15,14 +15,14 @@ static MATCHES: &[&str] = &[
async fn account_v1_getbyriotid_getbypuuid() -> Result<(), String> {
// Game name is case and whitespace insensitive.
// But tag cannot have spaces. (Is it case sensitive?).
let account_tag = RIOT_API
let account_tag = riot_api()
.account_v1()
.get_by_riot_id(ROUTE, "Lug nuts K", "000")
.await
.map_err(|e| format!("Failed to get account by riot ID: {}", e))?
.ok_or("Riot account not found!".to_owned())?;
let account_puuid = RIOT_API
let account_puuid = riot_api()
.account_v1()
.get_by_puuid(ROUTE, &account_tag.puuid)
.await
@ -36,7 +36,7 @@ async fn account_v1_getbyriotid_getbypuuid() -> Result<(), String> {
/// Tournament stub test.
#[tokio_shared_rt::test]
async fn tournamentstub() -> Result<(), String> {
let ts = RIOT_API.tournament_stub_v5();
let ts = riot_api().tournament_stub_v5();
let provider_id = ts
.register_provider_data(
ROUTE,

View File

@ -25,7 +25,7 @@ static MATCHES: &[&str] = &[
/// Summoner tests.
#[tokio_shared_rt::test]
async fn summoner_get_kanjikana() -> Result<(), String> {
let p = RIOT_API
let p = riot_api()
.summoner_v4()
.get_by_summoner_name(ROUTE, "私の 頭が かたい");
let s = p
@ -41,7 +41,7 @@ async fn summoner_get_kanjikana() -> Result<(), String> {
// /// Make sure get_raw_response(...) with invalid path fails as expected.
// #[tokio_shared_rt::test]
// async fn raw_response_invalid -> Result<(), String> {
// let p = RIOT_API.get_raw_response("summoner-v4.getBySummonerName", Region::JP.into(), "INVALID/PATH".to_owned(), None);
// let p = riot_api().get_raw_response("summoner-v4.getBySummonerName", Region::JP.into(), "INVALID/PATH".to_owned(), None);
// let r = p.await;
// rassert!(r.is_err());
// Ok(())
@ -55,8 +55,8 @@ async fn get_nonoptional_invalid() -> Result<(), String> {
"/lol/summoner/v4/summoners/by-name/{}",
"SUMMONER THAT DOES NOT EXIST"
);
let request = RIOT_API.request(reqwest::Method::GET, ROUTE.into(), &path_string);
let p = RIOT_API.execute_val::<riven::models::summoner_v4::Summoner>(
let request = riot_api().request(reqwest::Method::GET, ROUTE.into(), &path_string);
let p = riot_api().execute_val::<riven::models::summoner_v4::Summoner>(
"summoner-v4.getBySummonerName",
ROUTE.into(),
request,
@ -69,7 +69,7 @@ async fn get_nonoptional_invalid() -> Result<(), String> {
/// Check invalid code, make sure 403 is handled as expected.
#[tokio_shared_rt::test]
async fn tournament_forbidden() -> Result<(), String> {
let p = RIOT_API
let p = riot_api()
.tournament_v5()
.get_tournament_code(ROUTE.to_regional(), "INVALID_CODE");
let r = p.await;
@ -86,9 +86,9 @@ async fn tournament_forbidden() -> Result<(), String> {
// /// https://github.com/MingweiSamuel/Riven/issues/25
// #[tokio_shared_rt::test]
// async fn tft_league_getleagueentriesforsummoner() -> Result<(), String> {
// let sp = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, "Caihonbbt");
// let sp = riot_api().summoner_v4().get_by_summoner_name(ROUTE, "Caihonbbt");
// let sr = sp.await.map_err(|e| e.to_string())?.ok_or_else(|| "Failed to get \"Caihonbbt\"".to_owned())?;
// let lp = RIOT_API.tft_league_v1().get_league_entries_for_summoner(ROUTE, &sr.id);
// let lp = riot_api().tft_league_v1().get_league_entries_for_summoner(ROUTE, &sr.id);
// let lr = lp.await.map_err(|e| e.to_string())?;
// rassert!(!lr.is_empty());
// Ok(())
@ -98,7 +98,7 @@ async fn tournament_forbidden() -> Result<(), String> {
/// https://github.com/MingweiSamuel/Riven/issues/24
#[tokio_shared_rt::test]
async fn tft_league_gettopratedladder() -> Result<(), String> {
let lp = RIOT_API
let lp = riot_api()
.tft_league_v1()
.get_top_rated_ladder(ROUTE, QueueType::RANKED_TFT_TURBO);
let lr = lp.await.map_err(|e| e.to_string())?;

View File

@ -8,7 +8,7 @@ const ROUTE: PlatformRoute = PlatformRoute::EUW1;
#[tokio_shared_rt::test]
async fn championmastery_getscore_ma5tery() -> Result<(), String> {
let sum = RIOT_API
let sum = riot_api()
.summoner_v4()
.get_by_summoner_name(ROUTE, "ma5tery");
let sum = sum
@ -16,7 +16,7 @@ async fn championmastery_getscore_ma5tery() -> Result<(), String> {
.map_err(|e| format!("Error getting summoner: {}", e))?
.ok_or_else(|| "Failed to find summoner".to_owned())?;
let p = RIOT_API
let p = riot_api()
.champion_mastery_v4()
.get_champion_mastery_score_by_puuid(ROUTE, &sum.puuid);
let s = p
@ -32,7 +32,7 @@ async fn championmastery_getscore_ma5tery() -> Result<(), String> {
#[tokio_shared_rt::test]
async fn championmastery_getall_ma5tery() -> Result<(), String> {
let sum = RIOT_API
let sum = riot_api()
.summoner_v4()
.get_by_summoner_name(ROUTE, "ma5tery");
let sum = sum
@ -40,7 +40,7 @@ async fn championmastery_getall_ma5tery() -> Result<(), String> {
.map_err(|e| format!("Error getting summoner: {}", e))?
.ok_or_else(|| "Failed to find summoner".to_owned())?;
let p = RIOT_API
let p = riot_api()
.champion_mastery_v4()
.get_all_champion_masteries_by_puuid(ROUTE, &sum.puuid);
let s = p
@ -53,7 +53,7 @@ async fn championmastery_getall_ma5tery() -> Result<(), String> {
/// https://github.com/RiotGames/developer-relations/issues/602
#[tokio_shared_rt::test]
async fn spectator_combo() -> Result<(), String> {
let featured_p = RIOT_API.spectator_v4().get_featured_games(ROUTE);
let featured_p = riot_api().spectator_v4().get_featured_games(ROUTE);
let featured = featured_p.await.map_err(|e| e.to_string())?;
if featured.game_list.is_empty() {
@ -62,7 +62,7 @@ async fn spectator_combo() -> Result<(), String> {
}
// let summoner_name = &featured.game_list[0].participants[0].summoner_name;
// let summoner_p = RIOT_API.summoner_v4().get_by_summoner_name(ROUTE, summoner_name);
// let summoner_p = riot_api().summoner_v4().get_by_summoner_name(ROUTE, summoner_name);
// let summoner = summoner_p.await.map_err(|e| e.to_string())?.ok_or_else(|| "Failed to find summoner".to_owned())?;
let featured_game = &featured.game_list[0];
@ -74,7 +74,7 @@ async fn spectator_combo() -> Result<(), String> {
)
})?;
let livegame_p = RIOT_API
let livegame_p = riot_api()
.spectator_v4()
.get_current_game_info_by_summoner(ROUTE, &summoner_id);
let livegame_o = livegame_p.await.map_err(|e| e.to_string())?;

View File

@ -22,14 +22,14 @@ async fn tftmatchv1_get_list() -> Result<(), String> {
// /// Don't have acecess to tft-status-v1.
// #[tokio_shared_rt::test]
// async fn tftstatusv1_getplatformdata() -> Result<(), String> {
// let p = RIOT_API.tft_status_v1().get_platform_data(ROUTE);
// let p = riot_api().tft_status_v1().get_platform_data(ROUTE);
// let _s = p.await.map_err(|e| e.to_string())?;
// Ok(())
// }
#[tokio_shared_rt::test]
async fn tftleaguev1_gettopratedladder() -> Result<(), String> {
let p = RIOT_API
let p = riot_api()
.tft_league_v1()
.get_top_rated_ladder(ROUTE, QueueType::RANKED_TFT_TURBO);
let l = p.await.map_err(|e| e.to_string())?;
@ -43,7 +43,7 @@ async fn tftleaguev1_gettopratedladder() -> Result<(), String> {
#[tokio_shared_rt::test]
async fn tftmatchv1_getmatch() -> Result<(), String> {
let p = RIOT_API
let p = riot_api()
.tft_match_v1()
.get_match(ROUTE.to_regional(), "EUW1_6455483163");
let _m = p
@ -55,7 +55,7 @@ async fn tftmatchv1_getmatch() -> Result<(), String> {
#[tokio_shared_rt::test]
async fn tftsummonerv1_getbyname() -> Result<(), String> {
let p = RIOT_API
let p = riot_api()
.tft_summoner_v1()
.get_by_summoner_name(ROUTE, "相当猥琐");
let _s = p
@ -67,7 +67,7 @@ async fn tftsummonerv1_getbyname() -> Result<(), String> {
#[tokio_shared_rt::test]
async fn tftsummonerv1_getbyname_none() -> Result<(), String> {
let p = RIOT_API
let p = riot_api()
.tft_summoner_v1()
.get_by_summoner_name(ROUTE, "this summoner does not exist");
rassert!(p.await.map_err(|e| e.to_string())?.is_none());
@ -77,13 +77,13 @@ async fn tftsummonerv1_getbyname_none() -> Result<(), String> {
/// Get top rated player, get some of their matches.
#[tokio_shared_rt::test]
async fn tft_combo() -> Result<(), String> {
let top_players = RIOT_API
let top_players = riot_api()
.tft_league_v1()
.get_top_rated_ladder(ROUTE, QueueType::RANKED_TFT_TURBO);
let top_players = top_players.await.map_err(|e| e.to_string())?;
rassert!(!top_players.is_empty());
let top_player_entry = &top_players[0];
let top_player = RIOT_API
let top_player = riot_api()
.tft_summoner_v1()
.get_by_summoner_id(ROUTE, &top_player_entry.summoner_id);
let top_player = top_player.await.map_err(|e| e.to_string())?;
@ -91,7 +91,7 @@ async fn tft_combo() -> Result<(), String> {
"Top player is {} with `puuid` {}.",
top_player.name, top_player.puuid
);
let match_ids = RIOT_API.tft_match_v1().get_match_ids_by_puuid(
let match_ids = riot_api().tft_match_v1().get_match_ids_by_puuid(
ROUTE.to_regional(),
&top_player.puuid,
Some(10),

View File

@ -21,7 +21,7 @@ async_tests!{
let leagues = (1..10)
.map(async move |i| {
let leaguelist = RIOT_API.league_v4().get_league_entries(REGION,
let leaguelist = riot_api().league_v4().get_league_entries(REGION,
QueueType::RANKED_SOLO_5x5, Tier::GOLD, Division::III, Some(i));
let leaguelist = leaguelist.await
.map_err(|e| e.to_string())?
@ -32,7 +32,7 @@ async_tests!{
let summoners = leaguelist
.iter()
.map(async move |leagueentry| {
let summonerfuture = RIOT_API.summoner_v4().get_by_summoner_id(
let summonerfuture = riot_api().summoner_v4().get_by_summoner_id(
REGION, &leagueentry.summoner_id);
summonerfuture.await
.map_err(|e| e.to_string())?

View File

@ -1,6 +1,6 @@
mod testutils;
use riven::consts::*;
use testutils::RIOT_API;
use testutils::riot_api;
const ROUTE: PlatformRoute = PlatformRoute::LA1;
@ -12,7 +12,7 @@ const CHALLENGE_ID_ARAM_1K_DPM: i64 = 101101;
#[tokio_shared_rt::test]
async fn lol_challenges_v1_leaderboards_playerdata() -> Result<(), String> {
let challenge_id = CHALLENGE_ID_ARAM_1K_DPM;
let leaderboard = RIOT_API
let leaderboard = riot_api()
.lol_challenges_v1()
.get_challenge_leaderboards(ROUTE, challenge_id, Tier::GRANDMASTER, None)
.await
@ -38,7 +38,7 @@ async fn lol_challenges_v1_leaderboards_playerdata() -> Result<(), String> {
// Spot check 10% for `player-data`.
for entry in leaderboard.iter().step_by(10) {
let _player_data = RIOT_API
let _player_data = riot_api()
.lol_challenges_v1()
.get_player_data(ROUTE, &entry.puuid)
.await
@ -52,7 +52,7 @@ async fn lol_challenges_v1_leaderboards_playerdata() -> Result<(), String> {
/// /lol/challenges/v1/challenges/{challengeId}/config
#[tokio_shared_rt::test]
async fn lol_challenges_v1_check_configs() -> Result<(), String> {
let challenges = RIOT_API
let challenges = riot_api()
.lol_challenges_v1()
.get_all_challenge_configs(ROUTE)
.await
@ -66,7 +66,7 @@ async fn lol_challenges_v1_check_configs() -> Result<(), String> {
// Spot-check 10% of the challenge IDs.
for challenge in challenges.iter().step_by(10) {
RIOT_API
riot_api()
.lol_challenges_v1()
.get_challenge_configs(ROUTE, challenge.id)
.await
@ -87,7 +87,7 @@ async fn lol_challenges_v1_check_configs() -> Result<(), String> {
#[tokio_shared_rt::test]
async fn lol_challenges_v1_check_percentiles() -> Result<(), String> {
// Check all percentiles.
let percentiles = RIOT_API
let percentiles = riot_api()
.lol_challenges_v1()
.get_all_challenge_percentiles(ROUTE)
.await
@ -96,7 +96,7 @@ async fn lol_challenges_v1_check_percentiles() -> Result<(), String> {
// Spot-check 10% of the challenge IDs.
for &challenge_id in percentiles.keys().step_by(10) {
RIOT_API
riot_api()
.lol_challenges_v1()
.get_challenge_percentiles(ROUTE, challenge_id)
.await

View File

@ -21,10 +21,10 @@ const ROUTE: PlatformRoute = PlatformRoute::NA1;
#[tokio_shared_rt::test]
async fn summoner_double() -> Result<(), String> {
let l1p = RIOT_API
let l1p = riot_api()
.summoner_v4()
.get_by_summoner_name(ROUTE, "lug nuts k");
let l2p = RIOT_API
let l2p = riot_api()
.summoner_v4()
.get_by_summoner_name(ROUTE, "lugnuts k");
let l1 = l1p
@ -41,7 +41,7 @@ async fn summoner_double() -> Result<(), String> {
#[tokio_shared_rt::test]
async fn champion_getrotation() -> Result<(), String> {
let p = RIOT_API.champion_v3().get_champion_info(ROUTE);
let p = riot_api().champion_v3().get_champion_info(ROUTE);
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();
@ -54,7 +54,7 @@ async fn champion_getrotation() -> Result<(), String> {
#[tokio_shared_rt::test]
async fn leagueexp_get() -> Result<(), String> {
let p = RIOT_API.league_exp_v4().get_league_entries(
let p = riot_api().league_exp_v4().get_league_entries(
ROUTE,
QueueType::RANKED_SOLO_5x5,
Tier::CHALLENGER,
@ -70,14 +70,14 @@ async fn leagueexp_get() -> Result<(), String> {
#[tokio_shared_rt::test]
async fn champion_mastery_v4() -> Result<(), String> {
let summoner = RIOT_API
let summoner = riot_api()
.summoner_v4()
.get_by_summoner_name(ROUTE, "LugnutsK");
let summoner = summoner
.await
.map_err(|e| e.to_string())?
.ok_or_else(|| "'LugnutsK' not found!".to_owned())?;
let masteries = RIOT_API
let masteries = riot_api()
.champion_mastery_v4()
.get_all_champion_masteries_by_puuid(ROUTE, &summoner.puuid);
let masteries = masteries.await.map_err(|e| e.to_string())?;
@ -89,7 +89,7 @@ async fn champion_mastery_v4() -> Result<(), String> {
// /// LOR
// #[tokio_shared_rt::test]
// async fn async fn lor_ranked_get_leaderboards() -> Result<(), String> {
// let future = RIOT_API.lor_ranked_v1().get_leaderboards(Region::AMERICAS);
// let future = riot_api().lor_ranked_v1().get_leaderboards(Region::AMERICAS);
// let _leaderboard = future.await.map_err(|e| e.to_string())?;
// Ok(())
// }
@ -98,10 +98,10 @@ async fn champion_mastery_v4() -> Result<(), String> {
#[tokio_shared_rt::test]
async fn clash_get_tournaments() -> Result<(), String> {
let p = RIOT_API.clash_v1().get_tournaments(ROUTE);
let p = riot_api().clash_v1().get_tournaments(ROUTE);
let tours = p.await.map_err(|e| e.to_string())?;
if let Some(tour0) = tours.first() {
let p = RIOT_API.clash_v1().get_tournament_by_id(ROUTE, tour0.id);
let p = riot_api().clash_v1().get_tournament_by_id(ROUTE, tour0.id);
let tour1 = p.await.map_err(|e| e.to_string())?;
assert_eq!(Some(tour0.id), tour1.map(|t| t.id));
}
@ -110,7 +110,7 @@ async fn clash_get_tournaments() -> Result<(), String> {
#[tokio_shared_rt::test]
async fn clash_get_team_by_id_invalid() -> Result<(), String> {
let p = RIOT_API
let p = riot_api()
.clash_v1()
.get_team_by_id(ROUTE, "00000000-0000-0000-0000-000000000000");
let team = p.await.map_err(|e| e.to_string())?;
@ -120,7 +120,7 @@ async fn clash_get_team_by_id_invalid() -> Result<(), String> {
#[tokio_shared_rt::test]
async fn status() -> Result<(), String> {
let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE);
let p = riot_api().lol_status_v4().get_platform_data(ROUTE);
let status = p.await.map_err(|e| e.to_string())?;
println!("{:?}", status);
Ok(())

View File

@ -6,7 +6,7 @@ const ROUTE: PlatformRoute = PlatformRoute::PH2;
#[tokio_shared_rt::test]
async fn status() -> Result<(), String> {
let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE);
let p = riot_api().lol_status_v4().get_platform_data(ROUTE);
let status = p.await.map_err(|e| e.to_string())?;
println!("{:?}", status);
Ok(())

View File

@ -6,7 +6,7 @@ const ROUTE: PlatformRoute = PlatformRoute::SG2;
#[tokio_shared_rt::test]
async fn status() -> Result<(), String> {
let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE);
let p = riot_api().lol_status_v4().get_platform_data(ROUTE);
let status = p.await.map_err(|e| e.to_string())?;
println!("{:?}", status);
Ok(())

View File

@ -6,7 +6,7 @@ const ROUTE: PlatformRoute = PlatformRoute::TH2;
#[tokio_shared_rt::test]
async fn status() -> Result<(), String> {
let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE);
let p = riot_api().lol_status_v4().get_platform_data(ROUTE);
let status = p.await.map_err(|e| e.to_string())?;
println!("{:?}", status);
Ok(())

View File

@ -1,13 +1,13 @@
mod testutils;
use riven::consts::*;
use riven::models::summoner_v4::Summoner;
use testutils::RIOT_API;
use testutils::riot_api;
const ROUTE: PlatformRoute = PlatformRoute::TR1;
#[tokio_shared_rt::test]
async fn league_summoner_bulk_test() -> Result<(), String> {
let p = RIOT_API
let p = riot_api()
.league_v4()
.get_challenger_league(ROUTE, QueueType::RANKED_SOLO_5x5);
// let p = future_start(p);
@ -20,7 +20,7 @@ async fn league_summoner_bulk_test() -> Result<(), String> {
.iter()
.take(50)
.map(|entry| {
RIOT_API
riot_api()
.summoner_v4()
.get_by_summoner_id(ROUTE, &entry.summoner_id)
})

View File

@ -1,12 +1,14 @@
mod testutils;
use riven::consts::*;
use testutils::RIOT_API;
use testutils::riot_api;
const ROUTE: ValPlatformRoute = ValPlatformRoute::LATAM;
#[tokio_shared_rt::test]
async fn val_content_ranked_test() -> Result<(), String> {
let p = RIOT_API.val_content_v1().get_content(ROUTE, Some("zh-CN"));
let p = riot_api()
.val_content_v1()
.get_content(ROUTE, Some("zh-CN"));
let contents = p
.await
.map_err(|e| format!("Failed to get content: {}", e))?;
@ -24,7 +26,7 @@ async fn val_content_ranked_test() -> Result<(), String> {
})
.ok_or(format!("No active acts of {} found.", contents.acts.len()))?;
let p = RIOT_API
let p = riot_api()
.val_ranked_v1()
.get_leaderboard(ROUTE, &act.id, None, None);
let leaderboard = p.await.map_err(|e| e.to_string())?.ok_or(format!(

View File

@ -6,7 +6,7 @@ const ROUTE: PlatformRoute = PlatformRoute::VN2;
#[tokio_shared_rt::test]
async fn status() -> Result<(), String> {
let p = RIOT_API.lol_status_v4().get_platform_data(ROUTE);
let p = riot_api().lol_status_v4().get_platform_data(ROUTE);
let status = p.await.map_err(|e| e.to_string())?;
println!("{:?}", status);
Ok(())

View File

@ -1,8 +1,8 @@
#![allow(dead_code)]
use std::future::Future;
use std::sync::OnceLock;
use lazy_static::lazy_static;
use riven::consts::{PlatformRoute, QueueType, RegionalRoute};
use riven::{RiotApi, RiotApiConfig};
@ -36,23 +36,30 @@ macro_rules! rassert_ne {
};
}
lazy_static! {
pub static ref RIOT_API: RiotApi = {
static RIOT_API: OnceLock<RiotApi> = OnceLock::new();
pub fn riot_api() -> &'static RiotApi {
RIOT_API.get_or_init(|| {
// Initialize logger here, as a convenient trigger spot.
env_logger::init();
let api_key = std::env::var("RGAPI_KEY")
.ok()
.or_else(|| std::fs::read_to_string("apikey.txt").ok())
.or_else(|| {
use std::iter::FromIterator;
let path =
std::path::PathBuf::from_iter([env!("CARGO_MANIFEST_DIR"), "../apikey.txt"]);
std::fs::read_to_string(path).ok()
})
.expect("Failed to find RGAPI_KEY env var or apikey.txt.");
RiotApi::new(RiotApiConfig::with_key(api_key.trim()).preconfig_burst())
};
})
}
pub async fn league_v4_match_v5_latest_combo(route: PlatformRoute) -> Result<(), String> {
const NUM_MATCHES: usize = 10;
let challenger_future = RIOT_API
let challenger_future = riot_api()
.league_v4()
.get_challenger_league(route, QueueType::RANKED_SOLO_5x5);
let challenger_league = challenger_future
@ -77,14 +84,14 @@ pub async fn league_v4_match_v5_latest_combo(route: PlatformRoute) -> Result<(),
.iter()
.take(5)
.map(|entry| async move {
let summoner_future = RIOT_API
let summoner_future = riot_api()
.summoner_v4()
.get_by_summoner_id(route, &entry.summoner_id);
let summoner_info = summoner_future
.await
.map_err(|e| format!("Failed to find summoner info: {}", e))?;
let match_ids_future = RIOT_API.match_v5().get_match_ids_by_puuid(
let match_ids_future = riot_api().match_v5().get_match_ids_by_puuid(
route.to_regional(),
&summoner_info.puuid,
Some(5),
@ -119,7 +126,7 @@ pub async fn tft_match_v1_get(
) -> Result<(), String> {
let futures = matches.into_iter().map(|matche| async move {
let matche = matche.as_ref();
let p = RIOT_API.tft_match_v1().get_match(route, matche);
let p = riot_api().tft_match_v1().get_match(route, matche);
let m = p
.await
.map_err(|e| format!("Failed to get match {}: {:?}", matche, e))?
@ -158,7 +165,7 @@ pub async fn match_v5_get(
) -> Result<(), String> {
let futures = matches.into_iter().map(|matche| async move {
let matche = matche.as_ref();
let p = RIOT_API.match_v5().get_match(route, matche);
let p = riot_api().match_v5().get_match(route, matche);
let m = p
.await
.map_err(|e| format!("Failed to get match {}: {:?}", matche, e))?
@ -200,7 +207,7 @@ pub async fn match_v5_get_timeline(
) -> Result<(), String> {
let futures = matches.into_iter().map(|matche| async move {
let matche = matche.as_ref();
let p = RIOT_API.match_v5().get_timeline(route, matche);
let p = riot_api().match_v5().get_timeline(route, matche);
let m = p
.await
.map_err(|e| format!("Failed to get match {}: {:?}", matche, e))?