use std::error::Error; use std::fmt; use std::fmt::{Debug, Display, Formatter}; use wasm_bindgen::{JsCast, JsValue}; use wasm_bindgen_futures::JsFuture; use web_sys::{Request, RequestInit, RequestMode, Response}; #[derive(Debug, Clone, PartialEq)] pub struct FetchError { pub err: JsValue, } impl Display for FetchError { fn fmt(&self, f: &mut Formatter) -> fmt::Result { Debug::fmt(&self.err, f) } } impl Error for FetchError {} impl From for FetchError { fn from(value: JsValue) -> Self { Self { err: value } } } impl From for FetchError { fn from(e: serde_json::Error) -> Self { Self { err: JsValue::from(e.to_string()), } } } async fn send_request(request: Request) -> Result { let window = web_sys::window().unwrap(); let resp_value = JsFuture::from(window.fetch_with_request(&request)).await?; let resp: Response = resp_value.dyn_into()?; Ok(resp) } pub async fn get_json(url: &str) -> Result, FetchError> { let mut opts = RequestInit::new(); opts.method("GET"); opts.mode(RequestMode::Cors); let request = Request::new_with_str_and_init(url, &opts)?; request.headers().set("Accept", "application/json")?; let resp = self::send_request(request).await?; let text = JsFuture::from(resp.text()?).await?; Ok(text.as_string()) } pub async fn put(url: &str, data: JsValue) -> Result<(), FetchError> { let mut opts = RequestInit::new(); opts.method("PUT"); opts.mode(RequestMode::Cors); opts.body(Some(&data)); let request = Request::new_with_str_and_init(url, &opts)?; request.headers().set("Content-Type", "application/x-www-form-urlencoded")?; self::send_request(request).await?; Ok(()) }