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}