rusty_blitzcrank/
dispatcher.rs1pub mod dispatcher {
2 use crate::api_key::*;
3 use crate::types::*;
4 use reqwest::Client;
5 use tokio::time::{sleep, Duration};
6
7 pub async fn get(
8 url: String,
9 api_key: &mut ApiKey,
10 wait_for_rate_limit: bool,
11 endpoint: String,
12 ) -> Result<String, BlitzError> {
13 let is_limited = api_key.ratelimiter.is_limited(endpoint.clone());
14
15 if !wait_for_rate_limit && is_limited {
16 return Err(BlitzError::RateLimited);
17 } else if wait_for_rate_limit && is_limited {
18 sleep(Duration::from_secs(
19 api_key.ratelimiter.wait_for(endpoint.clone()),
20 ))
21 .await;
22 }
23
24 let client = Client::new();
25 api_key.ratelimiter.add_call(endpoint.clone());
26 let response = client
27 .get(url.clone())
28 .header("X-Riot-Token", &api_key.key)
29 .send()
30 .await;
31
32 let mut resp = match response {
33 Ok(d) => d,
34 Err(e) => return Err(BlitzError::RequestError(Some(e.to_string()))),
35 };
36
37 while resp.status().as_u16() == 429 {
38 let wait_time = resp
39 .headers()
40 .get("Retry-After")
41 .and_then(|h| h.to_str().ok())
42 .and_then(|s| s.parse().ok());
43
44 match wait_time {
45 Some(t) => {
46 if !wait_for_rate_limit {
47 return Err(BlitzError::RateLimited);
48 }
49
50 sleep(Duration::from_secs(t)).await;
51 resp = match client.get(url.clone()).send().await {
52 Ok(data) => data,
53 Err(e) => return Err(BlitzError::RequestError(Some(e.to_string()))),
54 };
55 }
56 None => break,
57 }
58 }
59
60 if resp.status().is_success() {
61 let data = resp.text().await.map(|b| b.to_owned());
62 match data {
63 Ok(d) => return Ok(d),
64 Err(e) => return Err(BlitzError::RequestError(Some(e.to_string()))),
65 }
66 } else if resp.status().as_u16() == 403 {
67 return Err(BlitzError::Forbidden);
68 } else if resp.status().as_u16() == 404 {
69 return Err(BlitzError::NotFound);
70 }
71
72 return Err(BlitzError::BadStatuscode(resp.status().as_u16()));
73 }
74}