rosu_render/client/
builder.rs

1use std::sync::Arc;
2
3use hyper_util::rt::TokioExecutor;
4
5use crate::{client::connector, model::Verification};
6
7use super::{ratelimiter::Ratelimiter, OrdrClient, OrdrRef};
8
9/// A builder for [`OrdrClient`].
10#[derive(Default)]
11#[must_use]
12pub struct OrdrClientBuilder {
13    verification: Option<Verification>,
14    ratelimit: Option<RatelimitBuilder>,
15}
16
17impl OrdrClientBuilder {
18    /// Create a new builder to create a [`OrdrClient`].
19    pub fn new() -> Self {
20        Self::default()
21    }
22
23    //// Build an [`OrdrClient`].
24    #[must_use]
25    pub fn build(self) -> OrdrClient {
26        let connector = connector::create();
27        let http =
28            hyper_util::client::legacy::Client::builder(TokioExecutor::new()).build(connector);
29
30        let ratelimit = match (self.verification.as_ref(), self.ratelimit) {
31            (None, None) => RatelimitBuilder::new(300_000, 1, 1), // One per 5 minutes
32            (None, Some(ratelimit)) => {
33                let ms_per_gain = ratelimit.interval / ratelimit.refill;
34
35                if ms_per_gain < 300_000 {
36                    RatelimitBuilder::new(300_000, 1, 1)
37                } else {
38                    RatelimitBuilder {
39                        max: ratelimit.max.min(2),
40                        ..ratelimit
41                    }
42                }
43            }
44            (Some(Verification::Key(_)), None) => RatelimitBuilder::new(10_000, 1, 1), // One per 10 seconds
45            (
46                Some(
47                    Verification::DevModeSuccess
48                    | Verification::DevModeFail
49                    | Verification::DevModeWsFail,
50                ),
51                None,
52            ) => RatelimitBuilder::new(1000, 1, 1), // One per second
53            (Some(_), Some(ratelimit)) => ratelimit,
54        };
55
56        OrdrClient {
57            inner: Arc::new(OrdrRef {
58                http,
59                ratelimiter: Ratelimiter::new(&ratelimit),
60                verification: self.verification,
61            }),
62        }
63    }
64
65    /// Specify a [`Verification`]
66    ///
67    /// Refer to its documentation for more information.
68    pub fn verification(self, verification: Verification) -> Self {
69        Self {
70            verification: Some(verification),
71            ..self
72        }
73    }
74
75    /// Specify a ratelimit that the client will uphold for the render endpoint.
76    /// Other endpoints won't be affected, they have a pre-set ratelimit.
77    ///
78    /// - `interval_ms`: How many milliseconds until the next refill
79    /// - `refill`: How many allowances are added per refill
80    /// - `max`: What's the maximum amount of available allowances
81    ///
82    /// If no [`Verification`] is specified, the ratelimit will be clamped up to one
83    /// per 5 minutes as per o!rdr rules.
84    /// If a dev mode [`Verification`] is specified, the ratelimit defaults to one per second.
85    /// If a verification key is specified, the ratelimit defaults to one per 10 seconds.
86    ///
87    /// # Panics
88    ///
89    /// Panics if `interval_ms` or `refill` are zero.
90    ///
91    /// # Example
92    /// ```
93    /// use rosu_render::OrdrClient;
94    ///
95    /// // Applying a ratelimit of 1 refill every 5 seconds, up to 2 charges
96    /// // which means 2 requests per 10 seconds.
97    /// let client = OrdrClient::builder()
98    ///     .render_ratelimit(5000, 1, 2)
99    ///     .build();
100    /// ```
101    pub fn render_ratelimit(self, interval_ms: u64, refill: u64, max: u64) -> Self {
102        Self {
103            ratelimit: Some(RatelimitBuilder::new(interval_ms, refill, max)),
104            ..self
105        }
106    }
107}
108
109pub(super) struct RatelimitBuilder {
110    pub interval: u64,
111    pub refill: u64,
112    pub max: u64,
113}
114
115impl RatelimitBuilder {
116    fn new(interval: u64, refill: u64, max: u64) -> Self {
117        Self {
118            interval,
119            refill,
120            max,
121        }
122    }
123}