lsp_web/
fetch.rs

1use std::collections::HashMap;
2
3// pub mod reqwest {
4//     pub use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
5//     pub use reqwest::Error;
6//     pub use reqwest::StatusCode;
7//     pub use reqwest::Url;
8// }
9use lsp_core::{
10    // client::reqwest::{HeaderMap, HeaderName, HeaderValue, Url},
11    client::Resp,
12};
13use serde::Serializer;
14use serde_json::json;
15use tracing::info;
16use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue};
17use web_sys::Response;
18
19#[wasm_bindgen]
20extern "C" {
21    #[wasm_bindgen(catch)]
22    async fn fetch(url: JsValue, options: JsValue) -> Result<JsValue, JsValue>;
23}
24
25pub async fn try_fetch(url: String, headers: HashMap<String, String>) -> Result<Resp, String> {
26    // if let Ok(url) = Url::parse(&url) {
27    //     if url.scheme() == "file" {
28    //         info!("Url scheme is file, let's do that! {}", url.path());
29    //         let body = read_file(url.path()).await?;
30    //         let status = 200;
31    //         let headers = HeaderMap::new();
32    //         return Ok(Resp {
33    //             headers,
34    //             body,
35    //             status,
36    //         });
37    //     }
38    // }
39
40    let ser: serde_wasm_bindgen::Serializer = serde_wasm_bindgen::Serializer::json_compatible();
41    let options_json = json!({ "headers": headers });
42    // let url = format!("https://proxy.linkeddatafragments.org/{}", url);
43    let options = ser
44        .serialize_some(&options_json)
45        .map_err(|_| String::from("failed to serialize headers"))?;
46
47    let resp_value = fetch(url.clone().into(), options)
48        .await
49        .map_err(|e| format!("{:?}", e))?;
50    info!("Got resp {}", url);
51
52    // `resp_value` is a `Response` object.
53    if !resp_value.is_instance_of::<Response>() {
54        return Err("Not a response!".into());
55    }
56
57    let resp: Response = resp_value.dyn_into().unwrap();
58    let status = resp.status();
59    let headers = resp.headers();
60    let headers: HashMap<String, String> =
61        serde_wasm_bindgen::from_value(headers.into()).map_err(|e| e.to_string())?;
62
63    let map: Vec<_> = headers.into_iter().map(|(k, v)| (k, v)).collect();
64
65    // Convert this other `Promise` into a rust `Future`.
66    let body = wasm_bindgen_futures::JsFuture::from(resp.text().map_err(|e| format!("{:?}", e))?)
67        .await
68        .map_err(|e| format!("{:?}", e))?
69        .as_string()
70        .ok_or(String::from("Not a string"))?;
71
72    Ok(Resp {
73        headers: map, // map,
74        body,
75        status,
76    })
77}
78
79pub async fn local_fetch(
80    url: String,
81    headers: HashMap<String, String>,
82    tx: futures::channel::oneshot::Sender<Result<Resp, String>>,
83) -> Result<wasm_bindgen::JsValue, wasm_bindgen::JsValue> {
84    let resp = try_fetch(url, headers).await;
85
86    tx.send(resp).unwrap();
87
88    Ok("".into())
89}