memory_serve/build/
mod.rs1use std::path::PathBuf;
2
3mod code;
4mod file_asset;
5mod list;
6
7const ASSET_FILE: &str = "memory_serve_assets.rs";
8const QUIET_ENV_NAME: &str = "MEMORY_SERVE_QUIET";
9
10pub use code::assets_to_code;
11
12pub fn load_directory<P: Into<PathBuf>>(path: P) {
15 let embed = !cfg!(debug_assertions) || cfg!(feature = "force-embed");
17
18 load_directory_with_embed(path, embed);
19}
20
21pub fn load_directory_with_embed<P: Into<PathBuf>>(path: P, embed: bool) {
23 load_names_directories(vec![("default", path)], embed);
24}
25
26pub fn load_names_directories<N, P>(named_paths: impl IntoIterator<Item = (N, P)>, embed: bool)
28where
29 N: Into<String>,
30 P: Into<PathBuf>,
31{
32 let out_dir: PathBuf = std::env::var("OUT_DIR")
33 .expect("OUT_DIR environment variable not set, make sure you call this from a build.rs")
34 .into();
35
36 println!("cargo::rerun-if-env-changed={QUIET_ENV_NAME}");
37 fn log(msg: &str) {
38 if std::env::var(QUIET_ENV_NAME) != Ok("1".to_string()) {
39 println!("cargo:warning={}", msg);
40 }
41 }
42
43 let mut code = "&[".to_string();
45
46 for (name, asset_dir) in named_paths {
47 let asset_dir = asset_dir
48 .into()
49 .canonicalize()
50 .expect("Could not canonicalize the provided path");
51 let asset_dir_label = asset_dir.to_string_lossy();
52 let assets = code::assets_to_code(&asset_dir_label, &asset_dir, &out_dir, embed, log);
53
54 println!("cargo::rerun-if-changed={asset_dir_label}");
55
56 code = format!("{code}(\"{}\", {assets}),", name.into());
57 }
58
59 code.push(']');
60
61 let target = out_dir.join(ASSET_FILE);
62
63 std::fs::write(target, code).expect("Unable to write memory-serve asset file.");
64}
65
66#[cfg(test)]
67pub(super) fn load_test_assets<P: Into<PathBuf>>(path: P) -> &'static [crate::Asset] {
69 fn log(msg: &str) {
70 println!("{}", msg);
71 }
72
73 let embed = !cfg!(debug_assertions) || cfg!(feature = "force-embed");
74 let assets = list::list_assets(&path.into(), embed, log);
75
76 let assets = assets
77 .into_iter()
78 .map(|fa| crate::Asset {
79 route: fa.route.leak(),
80 is_compressed: fa.compressed_bytes.is_some(),
81 path: fa.path.to_string_lossy().to_string().leak(),
82 etag: fa.etag.leak(),
83 content_type: fa.content_type.leak(),
84 bytes: fa.compressed_bytes.map(|v| {
85 let s: &'static [u8] = v.leak();
86
87 s
88 }),
89 should_compress: fa.should_compress,
90 })
91 .collect::<Vec<_>>();
92
93 Box::leak(assets.into_boxed_slice())
94}