fn0_deploy/
static_files.rs1use anyhow::{Result, anyhow};
2use std::path::{Path, PathBuf};
3
4pub struct StaticFile {
5 pub relative_path: String,
6 pub absolute_path: PathBuf,
7 pub size: u64,
8 pub content_type: &'static str,
9}
10
11pub fn collect_static_files(dir: &Path) -> Result<Vec<StaticFile>> {
12 let mut out = Vec::new();
13 if !dir.exists() {
14 return Ok(out);
15 }
16 walk_collect(dir, dir, &mut out)?;
17 Ok(out)
18}
19
20fn walk_collect(base: &Path, dir: &Path, out: &mut Vec<StaticFile>) -> Result<()> {
21 for entry in std::fs::read_dir(dir)? {
22 let entry = entry?;
23 let path = entry.path();
24 if path.is_dir() {
25 if path.file_name().and_then(|s| s.to_str()) == Some("ssr")
26 && path.parent() == Some(base)
27 {
28 continue;
29 }
30 walk_collect(base, &path, out)?;
31 continue;
32 }
33 let metadata = entry.metadata()?;
34 let rel = path
35 .strip_prefix(base)
36 .map_err(|e| anyhow!("strip_prefix: {e}"))?
37 .to_string_lossy()
38 .replace('\\', "/");
39 out.push(StaticFile {
40 relative_path: rel,
41 absolute_path: path.clone(),
42 size: metadata.len(),
43 content_type: content_type_for(&path),
44 });
45 }
46 Ok(())
47}
48
49pub fn content_type_for(path: &Path) -> &'static str {
50 match path.extension().and_then(|e| e.to_str()) {
51 Some("html") => "text/html; charset=utf-8",
52 Some("css") => "text/css; charset=utf-8",
53 Some("js") | Some("mjs") | Some("cjs") => "application/javascript; charset=utf-8",
54 Some("json") => "application/json; charset=utf-8",
55 Some("map") => "application/json; charset=utf-8",
56 Some("png") => "image/png",
57 Some("jpg") | Some("jpeg") => "image/jpeg",
58 Some("gif") => "image/gif",
59 Some("svg") => "image/svg+xml",
60 Some("ico") => "image/x-icon",
61 Some("webp") => "image/webp",
62 Some("woff") => "font/woff",
63 Some("woff2") => "font/woff2",
64 Some("ttf") => "font/ttf",
65 Some("otf") => "font/otf",
66 Some("eot") => "application/vnd.ms-fontobject",
67 Some("txt") => "text/plain; charset=utf-8",
68 Some("xml") => "application/xml; charset=utf-8",
69 Some("pdf") => "application/pdf",
70 Some("mp4") => "video/mp4",
71 Some("webm") => "video/webm",
72 Some("mp3") => "audio/mpeg",
73 Some("wav") => "audio/wav",
74 _ => "application/octet-stream",
75 }
76}