1use crate::{env::EnvBinding, RequestInit, Result};
2#[cfg(feature = "http")]
3use std::convert::TryInto;
4use wasm_bindgen::{JsCast, JsValue};
5use wasm_bindgen_futures::JsFuture;
6
7#[cfg(feature = "http")]
8use crate::{HttpRequest, HttpResponse};
9use crate::{Request, Response};
10#[derive(Debug, Clone)]
12pub struct Fetcher(worker_sys::Fetcher);
13
14#[cfg(not(feature = "http"))]
15type FetchResponseType = Response;
16#[cfg(feature = "http")]
17type FetchResponseType = HttpResponse;
18
19#[cfg(not(feature = "http"))]
20type FetchRequestType = Request;
21#[cfg(feature = "http")]
22type FetchRequestType = HttpRequest;
23
24impl Fetcher {
25 pub async fn fetch(
30 &self,
31 url: impl Into<String>,
32 init: Option<RequestInit>,
33 ) -> Result<FetchResponseType> {
34 let path = url.into();
35 let promise = match init {
36 Some(ref init) => self.0.fetch_with_str_and_init(&path, &init.into()),
37 None => self.0.fetch_with_str(&path),
38 }?;
39
40 let resp_sys: web_sys::Response = JsFuture::from(promise).await?.dyn_into()?;
41 #[cfg(not(feature = "http"))]
42 let result = Ok(Response::from(resp_sys));
43 #[cfg(feature = "http")]
44 let result = crate::response_from_wasm(resp_sys);
45 result
46 }
47
48 pub async fn fetch_request(&self, request: FetchRequestType) -> Result<FetchResponseType> {
56 #[cfg(feature = "http")]
57 let req = TryInto::<Request>::try_into(request)?;
58 #[cfg(not(feature = "http"))]
59 let req = request;
60 let promise = self.0.fetch(req.inner())?;
61 let resp_sys: web_sys::Response = JsFuture::from(promise).await?.dyn_into()?;
62 let response = Response::from(resp_sys);
63 #[cfg(feature = "http")]
64 let result = response.try_into();
65 #[cfg(not(feature = "http"))]
66 let result = Ok(response);
67 result
68 }
69
70 pub fn into_rpc<T: JsCast>(self) -> T {
90 self.0.unchecked_into()
91 }
92}
93
94impl EnvBinding for Fetcher {
95 const TYPE_NAME: &'static str = "Fetcher";
96}
97
98impl JsCast for Fetcher {
99 fn instanceof(val: &wasm_bindgen::JsValue) -> bool {
100 val.is_instance_of::<Fetcher>()
101 }
102
103 fn unchecked_from_js(val: wasm_bindgen::JsValue) -> Self {
104 Self(val.into())
105 }
106
107 fn unchecked_from_js_ref(val: &wasm_bindgen::JsValue) -> &Self {
108 unsafe { &*(val as *const JsValue as *const Self) }
109 }
110}
111
112impl From<Fetcher> for JsValue {
113 fn from(service: Fetcher) -> Self {
114 JsValue::from(service.0)
115 }
116}
117
118impl AsRef<wasm_bindgen::JsValue> for Fetcher {
119 fn as_ref(&self) -> &wasm_bindgen::JsValue {
120 &self.0
121 }
122}
123
124impl From<worker_sys::Fetcher> for Fetcher {
125 fn from(inner: worker_sys::Fetcher) -> Self {
126 Self(inner)
127 }
128}