1use crate::{env::EnvBinding, RequestInit, Result};
2use std::convert::TryInto;
3use wasm_bindgen::{JsCast, JsValue};
4use wasm_bindgen_futures::JsFuture;
5
6#[cfg(feature = "http")]
7use crate::HttpResponse;
8use crate::{Request, Response};
9#[derive(Debug, Clone)]
11pub struct Fetcher(worker_sys::Fetcher);
12
13#[cfg(not(feature = "http"))]
14type FetchResponseType = Response;
15#[cfg(feature = "http")]
16type FetchResponseType = HttpResponse;
17
18impl Fetcher {
19 pub async fn fetch(
24 &self,
25 url: impl Into<String>,
26 init: Option<RequestInit>,
27 ) -> Result<FetchResponseType> {
28 let path = url.into();
29 let promise = match init {
30 Some(ref init) => self.0.fetch_with_str_and_init(&path, &init.into()),
31 None => self.0.fetch_with_str(&path),
32 }?;
33
34 let resp_sys: web_sys::Response = JsFuture::from(promise).await?.dyn_into()?;
35 #[cfg(not(feature = "http"))]
36 let result = Ok(Response::from(resp_sys));
37 #[cfg(feature = "http")]
38 let result = crate::response_from_wasm(resp_sys);
39 result
40 }
41
42 pub async fn fetch_request<T, E>(&self, request: T) -> Result<FetchResponseType>
49 where
50 T: TryInto<Request, Error = E>,
51 crate::Error: From<E>,
52 {
53 let req = request.try_into()?;
54 let promise = self.0.fetch(req.inner())?;
55 let resp_sys: web_sys::Response = JsFuture::from(promise).await?.dyn_into()?;
56 let response = Response::from(resp_sys);
57 #[cfg(feature = "http")]
58 let result = response.try_into();
59 #[cfg(not(feature = "http"))]
60 let result = Ok(response);
61 result
62 }
63
64 pub fn into_rpc<T: JsCast>(self) -> T {
84 self.0.unchecked_into()
85 }
86}
87
88impl EnvBinding for Fetcher {
89 const TYPE_NAME: &'static str = "Fetcher";
90}
91
92impl JsCast for Fetcher {
93 fn instanceof(val: &wasm_bindgen::JsValue) -> bool {
94 val.is_instance_of::<Fetcher>()
95 }
96
97 fn unchecked_from_js(val: wasm_bindgen::JsValue) -> Self {
98 Self(val.into())
99 }
100
101 fn unchecked_from_js_ref(val: &wasm_bindgen::JsValue) -> &Self {
102 unsafe { &*(val as *const JsValue as *const Self) }
103 }
104}
105
106impl From<Fetcher> for JsValue {
107 fn from(service: Fetcher) -> Self {
108 JsValue::from(service.0)
109 }
110}
111
112impl AsRef<wasm_bindgen::JsValue> for Fetcher {
113 fn as_ref(&self) -> &wasm_bindgen::JsValue {
114 &self.0
115 }
116}
117
118impl From<worker_sys::Fetcher> for Fetcher {
119 fn from(inner: worker_sys::Fetcher) -> Self {
120 Self(inner)
121 }
122}