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