I am working on a simple web app using trunk
where I would like to copy several JSON file assets for runtime use in some Rust code. I saw this example where they use the copy-dir
to link assets, but in the example those assets are only being utilized in the HTML. How can I access those assets in Rust code?
I was hoping I could use fs::read_dir
to get all the assets in my copied directory, but so far that has only had the effect of stalling out the app, and I can understand maybe that shouldn't be used in the web app, so I'm left wondering what should I be doing to access those files from Rust code and not just in the HTML?
When HTML references an asset exported by copy-dir
, the browser automatically performs a network transaction to download it.
The Rust equivalent would be using the fetch
API:
pub async fn fetch_string(url: &str) -> Result<String, String> {
let opts = RequestInit::new();
opts.set_method("GET");
opts.set_mode(RequestMode::Cors);
let request = Request::new_with_str_and_init(url, &opts).map_err(|e| format!("{:?}", e))?;
let window = web_sys::window().unwrap();
let js_response = JsFuture::from(window.fetch_with_request(&request))
.await
.map_err(|e| format!("{:?}", e))?;
let response: Response = js_response.dyn_into().map_err(|e| format!("{:?}", e))?;
let text_promise = response.text().map_err(|e| format!("{:?}", e))?;
let text: String = JsFuture::from(text_promise)
.await
.map_err(|e| format!("{:?}", e))?
.as_string()
.ok_or(String::from("text not string"))?;
Ok(text)
}
future_to_promise(async {
let _json = json_fetch("/path/to/data.json").await.unwrap();
Ok(JsValue::UNDEFINED)
});
Here's a crate with a higher-level fetch
API: gloo_net
.
There is, however, an alternative. You can use the include_str!
macro to inline JSON into your Rust source code at compile time:
let json: &'static str = include_str!("./data.json");
A limitation of include_str!
is that it only supports single, named files and not directories. For directories, you can use include_dir
or rust_embed
.