54 lines
1.4 KiB
Rust
54 lines
1.4 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
use thiserror::Error;
|
|
use wasm_bindgen::{prelude::*, JsCast};
|
|
use wasm_bindgen_futures::JsFuture;
|
|
use web_sys::{Headers, Request, RequestInit, RequestMode, Response};
|
|
|
|
#[derive(Error, Debug)]
|
|
pub enum FetchError {
|
|
#[error("javascript error")]
|
|
JsError(JsValue),
|
|
#[error("failed to serialize json: {source:?}")]
|
|
SerializationError {
|
|
#[from]
|
|
source: serde_json::Error,
|
|
},
|
|
}
|
|
|
|
impl From<JsValue> for FetchError {
|
|
fn from(value: JsValue) -> Self {
|
|
Self::JsError(value)
|
|
}
|
|
}
|
|
|
|
pub async fn api_request<B: Serialize, R: for<'a> Deserialize<'a>>(
|
|
method: &str,
|
|
endpoint: &str,
|
|
body: Option<B>,
|
|
) -> Result<R, FetchError> {
|
|
let api_key = "7de10bf6-278d-11ed-ad60-a8a15919d1b3";
|
|
|
|
let mut req_opts = RequestInit::new();
|
|
req_opts.method(method);
|
|
|
|
let headers = Headers::new()?;
|
|
headers.append("X-API-Key", api_key)?;
|
|
req_opts.headers(&headers);
|
|
|
|
if let Some(body) = body {
|
|
let value = JsValue::from_serde(&body)?;
|
|
req_opts.body(Some(&value));
|
|
}
|
|
|
|
let request = Request::new_with_str_and_init(
|
|
&format!("http://localhost:8000/api/{}", endpoint),
|
|
&req_opts,
|
|
)?;
|
|
|
|
let window = web_sys::window().unwrap();
|
|
let resp_value = JsFuture::from(window.fetch_with_request(&request)).await?;
|
|
let resp: Response = resp_value.dyn_into().unwrap();
|
|
|
|
Ok(JsFuture::from(resp.json()?).await?.into_serde()?)
|
|
}
|