[go: up one dir, main page]

worker/
rate_limit.rs

1use crate::{send::SendFuture, EnvBinding, Result};
2use serde::{Deserialize, Serialize};
3use wasm_bindgen::{JsCast, JsValue};
4use wasm_bindgen_futures::JsFuture;
5use worker_sys::RateLimiter as RateLimiterSys;
6
7pub struct RateLimiter(RateLimiterSys);
8
9#[derive(Serialize, Deserialize)]
10struct RateLimitOptions {
11    key: String,
12}
13
14#[derive(Serialize, Deserialize)]
15pub struct RateLimitOutcome {
16    pub success: bool,
17}
18
19unsafe impl Send for RateLimiter {}
20unsafe impl Sync for RateLimiter {}
21
22impl EnvBinding for RateLimiter {
23    const TYPE_NAME: &'static str = "Ratelimit";
24}
25impl RateLimiter {
26    pub async fn limit(&self, key: String) -> Result<RateLimitOutcome> {
27        let arg = serde_wasm_bindgen::to_value(&RateLimitOptions { key })?;
28        let promise = self.0.limit(arg.into())?;
29        let fut = SendFuture::new(JsFuture::from(promise));
30        let result = fut.await?;
31        let outcome = serde_wasm_bindgen::from_value(result)?;
32        Ok(outcome)
33    }
34}
35
36impl JsCast for RateLimiter {
37    fn instanceof(val: &JsValue) -> bool {
38        val.is_instance_of::<RateLimiterSys>()
39    }
40
41    fn unchecked_from_js(val: JsValue) -> Self {
42        Self(val.into())
43    }
44
45    fn unchecked_from_js_ref(val: &JsValue) -> &Self {
46        unsafe { &*(val as *const JsValue as *const Self) }
47    }
48}
49
50impl From<RateLimiter> for JsValue {
51    fn from(limiter: RateLimiter) -> Self {
52        JsValue::from(limiter.0)
53    }
54}
55
56impl AsRef<JsValue> for RateLimiter {
57    fn as_ref(&self) -> &JsValue {
58        &self.0
59    }
60}
61
62impl From<RateLimiterSys> for RateLimiter {
63    fn from(inner: RateLimiterSys) -> Self {
64        Self(inner)
65    }
66}