wasm_web_helpers/
fetch.rs

1pub use reqwasm::http::{Request, Response};
2pub use wasm_bindgen::JsValue;
3
4use serde::de::{Deserialize, DeserializeOwned, Deserializer};
5
6use crate::error::{Error, ReqwasmResult, Result};
7
8#[derive(Copy, Clone)]
9pub struct MissingBody;
10
11impl<'de> Deserialize<'de> for MissingBody {
12    fn deserialize<D>(_deserializer: D) -> std::result::Result<Self, D::Error>
13    where
14        D: Deserializer<'de>,
15    {
16        Ok(Self)
17    }
18}
19
20#[derive(Default)]
21pub struct JsonFetcher;
22
23impl JsonFetcher {
24    pub fn fetch<Body: 'static + DeserializeOwned>(
25        request: Request,
26        callback: impl FnOnce(Result<(Response, Result<Body>)>) + 'static,
27    ) {
28        wasm_bindgen_futures::spawn_local(async move {
29            let result = fetch_success_json::<Body>(request).await;
30            callback(result);
31        });
32    }
33
34    pub fn send_get<Body: 'static + DeserializeOwned>(
35        uri: impl AsRef<str>,
36        callback: impl FnOnce(Result<(Response, Result<Body>)>) + 'static,
37    ) {
38        let request = Request::get(uri.as_ref());
39        Self::fetch(request, callback);
40    }
41
42    pub fn send_post<Body: 'static + DeserializeOwned>(
43        uri: impl AsRef<str>,
44        body: impl Into<JsValue>,
45        callback: impl FnOnce(Result<(Response, Result<Body>)>) + 'static,
46    ) {
47        let request = Request::post(uri.as_ref()).body(body);
48        Self::fetch(request, callback);
49    }
50
51    pub fn send_post_json<Body: 'static + DeserializeOwned>(
52        uri: impl AsRef<str>,
53        body: impl Into<JsValue>,
54        callback: impl FnOnce(Result<(Response, Result<Body>)>) + 'static,
55    ) {
56        let request = Request::post(uri.as_ref())
57            .header("Content-Type", "application/json")
58            .body(body);
59        Self::fetch(request, callback);
60    }
61}
62
63pub async fn fetch(request: Request) -> ReqwasmResult<Response> {
64    request.send().await
65}
66
67pub async fn fetch_text(request: Request) -> ReqwasmResult<(Response, ReqwasmResult<String>)> {
68    let response = request.send().await?;
69    let body = response.text().await;
70    Ok((response, body))
71}
72
73pub async fn fetch_json<Body: DeserializeOwned>(request: Request) -> ReqwasmResult<(Response, ReqwasmResult<Body>)> {
74    let response = request.send().await?;
75    let body = response.json().await;
76    Ok((response, body))
77}
78
79pub async fn fetch_success(request: Request) -> Result<Response> {
80    let response = request.send().await?;
81    let status = response.status();
82
83    if status == 200 {
84        Ok(response)
85    } else {
86        Err(Error::FailureResponse(status, format!("{:?}", response.text().await)))
87    }
88}
89
90pub async fn fetch_success_text(request: Request) -> Result<(Response, Result<String>)> {
91    let response = request.send().await?;
92    let body = response.text().await.map_err(Into::into);
93    let status = response.status();
94
95    if status == 200 {
96        Ok((response, body))
97    } else {
98        Err(Error::FailureResponse(status, format!("{:?}", body)))
99    }
100}
101
102pub async fn fetch_success_json<Body: DeserializeOwned>(request: Request) -> Result<(Response, Result<Body>)> {
103    let response = request.send().await?;
104    let status = response.status();
105
106    if status == 200 {
107        let body = response.json().await.map_err(Into::into);
108        Ok((response, body))
109    } else {
110        Err(Error::FailureResponse(status, format!("{:?}", response.text().await)))
111    }
112}