use std::ops::Deref;
use wasm_bindgen::JsCast;
use wasm_bindgen_futures::JsFuture;
use crate::{request::Request, response::Response, AbortSignal, Result};
pub enum Fetch {
Url(url::Url),
Request(Request),
}
impl Fetch {
pub async fn send(&self) -> Result<Response> {
match self {
Fetch::Url(url) => fetch_with_str(url.as_ref(), None).await,
Fetch::Request(req) => fetch_with_request(req, None).await,
}
}
pub async fn send_with_signal(&self, signal: &AbortSignal) -> Result<Response> {
match self {
Fetch::Url(url) => fetch_with_str(url.as_ref(), Some(signal)).await,
Fetch::Request(req) => fetch_with_request(req, Some(signal)).await,
}
}
}
async fn fetch_with_str(url: &str, signal: Option<&AbortSignal>) -> Result<Response> {
let mut init = web_sys::RequestInit::new();
init.signal(signal.map(|x| x.deref()));
let worker: web_sys::WorkerGlobalScope = js_sys::global().unchecked_into();
let promise = worker.fetch_with_str_and_init(url, &init);
let resp = JsFuture::from(promise).await?;
let resp: web_sys::Response = resp.dyn_into()?;
Ok(resp.into())
}
async fn fetch_with_request(request: &Request, signal: Option<&AbortSignal>) -> Result<Response> {
let mut init = web_sys::RequestInit::new();
init.signal(signal.map(|x| x.deref()));
let worker: web_sys::WorkerGlobalScope = js_sys::global().unchecked_into();
let req = request.inner();
let promise = worker.fetch_with_request_and_init(req, &init);
let resp = JsFuture::from(promise).await?;
let edge_response: web_sys::Response = resp.dyn_into()?;
Ok(edge_response.into())
}