Skip to main content

worker/
browser_rendering.rs

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