Skip to main content

worker/
dynamic_worker_loader.rs

1use crate::send::SendFuture;
2use crate::{env::EnvBinding, Error, Result};
3use serde::de::DeserializeOwned;
4use wasm_bindgen::{JsCast, JsValue};
5use wasm_bindgen_futures::JsFuture;
6use worker_sys::DynamicWorkerLoader as DynamicWorkerLoaderSys;
7
8#[derive(Debug, Clone)]
9pub struct DynamicWorkerLoader(DynamicWorkerLoaderSys);
10
11unsafe impl Send for DynamicWorkerLoader {}
12unsafe impl Sync for DynamicWorkerLoader {}
13
14impl DynamicWorkerLoader {
15    pub async fn load(&self, worker_name: &str) -> Result<JsValue> {
16        let promise = self.0.load(worker_name)?;
17        let output = SendFuture::new(JsFuture::from(promise)).await;
18        output.map_err(Error::from)
19    }
20
21    pub async fn load_json<T: DeserializeOwned>(&self, worker_name: &str) -> Result<T> {
22        let value = self.load(worker_name).await?;
23        Ok(serde_wasm_bindgen::from_value(value)?)
24    }
25}
26
27impl EnvBinding for DynamicWorkerLoader {
28    const TYPE_NAME: &'static str = "Object";
29
30    fn get(val: JsValue) -> Result<Self> {
31        if !val.is_object() {
32            return Err("Binding cannot be cast to DynamicWorkerLoader from non-object value".into());
33        }
34
35        let has_load = js_sys::Reflect::has(&val, &JsValue::from("load"))?;
36        if !has_load {
37            return Err("Binding cannot be cast to DynamicWorkerLoader: missing `load` method".into());
38        }
39
40        Ok(Self(val.unchecked_into()))
41    }
42}
43
44impl JsCast for DynamicWorkerLoader {
45    fn instanceof(val: &JsValue) -> bool {
46        val.is_object()
47    }
48
49    fn unchecked_from_js(val: JsValue) -> Self {
50        Self(val.unchecked_into())
51    }
52
53    fn unchecked_from_js_ref(val: &JsValue) -> &Self {
54        unsafe { &*(val as *const JsValue as *const Self) }
55    }
56}
57
58impl AsRef<JsValue> for DynamicWorkerLoader {
59    fn as_ref(&self) -> &JsValue {
60        &self.0
61    }
62}
63
64impl From<JsValue> for DynamicWorkerLoader {
65    fn from(val: JsValue) -> Self {
66        Self(val.unchecked_into())
67    }
68}
69
70impl From<DynamicWorkerLoader> for JsValue {
71    fn from(value: DynamicWorkerLoader) -> Self {
72        value.0.into()
73    }
74}