Skip to main content

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