rustwebassemblytrunk-rs

Utilize copied assets for Trunk web app in Rust code


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?


Solution

  • 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.