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