//! Generates a compile-time manifest of the asset files served on wasm, so //! the web entrypoint can preload them before the first frame. //! //! `WASM_ASSETS` is emitted into `OUT_DIR` and included by //! `src/wasm_assets.rs` on wasm targets. Native builds keep using //! `rust-embed` and ignore it. use std::path::Path; use std::{env, fs}; fn main() { let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set by cargo"); let assets_dir = Path::new(&manifest_dir).join("../../assets"); let mut paths = Vec::new(); for dir in ["icons", "brand"] { let dir_path = assets_dir.join(dir); let entries = fs::read_dir(&dir_path).unwrap_or_else(|error| { panic!( "expected asset directory {} to exist: {error}", dir_path.display() ) }); for entry in entries { let entry = entry.expect("failed to read asset directory entry"); if entry.file_type().is_ok_and(|t| t.is_file()) { let name = entry.file_name().to_string_lossy().into_owned(); if !name.starts_with('.') { paths.push(format!("{dir}/{name}")); } } } } paths.sort(); let manifest = format!( "/// Asset files served by the wasm asset loader. Generated by build.rs.\npub const WASM_ASSETS: &[&str] = &[\n{}\n];\n", paths .iter() .map(|path| format!(" \"{path}\",")) .collect::>() .join("\n") ); let out_dir = env::var("OUT_DIR").expect("OUT_DIR not set by cargo"); fs::write(Path::new(&out_dir).join("wasm_assets.rs"), manifest) .expect("failed to write wasm asset manifest"); // Rerun when the asset files change (adding/removing files updates the // directory mtime). for dir in ["icons", "brand"] { if let Ok(canonical) = assets_dir.join(dir).canonicalize() { println!("cargo:rerun-if-changed={}", canonical.display()); } } println!("cargo:rerun-if-changed=build.rs"); }