google_maps/request_rate/
with_rate.rs

1use crate::request_rate::{api::Api, api_rate::ApiRate, target_rate::TargetRate, RequestRate}; // use crate::request_rate
2use std::time::Duration;
3use stream_throttle::{ThrottlePool, ThrottleRate};
4
5// =============================================================================
6
7impl RequestRate {
8    // -------------------------------------------------------------------------
9    //
10    /// Specifies the request rate for the selected API. _Do not use this method
11    /// to set request rate limits, use `ClientSettings.with_rate()` instead_.
12    ///
13    /// ## Arguments
14    ///
15    /// * `api` ‧ Which Google Maps API are you setting the rate limit for? For
16    ///   example, `Api::Directions`, `Api::DistanceMatrix`, `Api::Elevation`,
17    ///   `Api::Geocoding`, `Api::TimeZone`, and so on. The `Api::All` rate limit
18    ///   is applied to all Google Maps API requests _in addition_ to the per-API
19    ///   rate limits.
20    ///
21    /// * `requests` ‧ The number of requests the client library is attempting
22    ///   to target. For example, _2 requests_ per 1 hour.
23    ///
24    /// * `duration` ‧ The duration for the targeted request rate. For example,
25    ///   1 request _per 1 minute_. This can be defined using the
26    ///   `std::time::Duration` methods.
27    ///
28    /// ## Examples:
29    ///
30    /// * Sets the rate limit for all Google Maps API requests to _2 request per
31    ///   minute_:
32    /// ```rust
33    /// with_rate(Api::All, 2, Duration::from_secs(60)) // 1 minute
34    /// ```
35    ///
36    /// * Sets the rate limit for Google Maps Elevation API requests to _1
37    ///   requests per second_:
38    /// ```rust
39    /// with_rate(Api::All, 1, Duration::from_secs(1)) // 1 second
40    /// ```
41    ///
42    /// * This method can be stacked:
43    /// ```rust
44    /// with_rate(Api::All, 1, Duration::from_secs(60)) // 1 minute
45    /// with_rate(Api::Directions, 1, Duration::from_secs(3_600)) // 1 hour
46    /// with_rate(Api::TimeZone, 2, Duration::from_secs(60)) // 1 second
47    /// ```
48    pub fn with_rate(&mut self, api: &Api, requests: u16, duration: Duration) -> &mut Self {
49        // Select `RequestRate` field for the API specified by the caller.
50        let api_ref = self.rate_map.get_mut(api);
51        let throttle_pool = if requests == 0 {
52            None
53        } else {
54            let throttle_rate = ThrottleRate::new(requests as usize, duration);
55            Some(ThrottlePool::new(throttle_rate))
56        };
57
58        // Has the ApiRate been set already?
59        match api_ref {
60            // If not, initialize the structure:
61            None => {
62                self.rate_map.insert(
63                    api.clone(),
64                    ApiRate {
65                        target_rate: TargetRate { requests, duration },
66                        throttle_pool,
67                    },
68                );
69            }
70            // If it has, set the new target request rate but preserve the
71            // current effective request rate:
72            Some(api_rate) => {
73                *api_rate = ApiRate {
74                    // Set new target request rate:
75                    target_rate: TargetRate { requests, duration },
76                    throttle_pool,
77                };
78            } // ApiRate
79        } // match
80
81        self
82    } // fn
83} // impl