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