venus_server/
embedded_frontend.rs1use axum::{
7 body::Body,
8 http::{header, Response, StatusCode},
9};
10use rust_embed::Embed;
11
12#[derive(Embed)]
14#[folder = "src/frontend/"]
15pub struct FrontendAssets;
16
17pub fn serve_static(path: String) -> Response<Body> {
19 let path = path.strip_prefix('/').map(|s| s.to_string()).unwrap_or(path);
21
22 match FrontendAssets::get(&path) {
23 Some(content) => {
24 let mime = mime_guess::from_path(&path)
25 .first_or_octet_stream()
26 .to_string();
27
28 Response::builder()
29 .status(StatusCode::OK)
30 .header(header::CONTENT_TYPE, mime)
31 .header(header::CACHE_CONTROL, "no-cache, no-store, must-revalidate")
32 .body(Body::from(content.data.into_owned()))
33 .unwrap()
34 }
35 None => Response::builder()
36 .status(StatusCode::NOT_FOUND)
37 .body(Body::from("Not Found"))
38 .unwrap(),
39 }
40}
41
42pub fn serve_index() -> Response<Body> {
44 serve_static("index.html".to_string())
45}
46
47pub fn is_available() -> bool {
49 FrontendAssets::get("index.html").is_some()
50}
51
52pub fn list_files() -> Vec<String> {
54 FrontendAssets::iter().map(|s| s.to_string()).collect()
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn test_frontend_assets_available() {
63 assert!(is_available(), "index.html should be embedded");
64 }
65
66 #[test]
67 fn test_list_files() {
68 let files = list_files();
69 assert!(files.iter().any(|f| f == "index.html"));
70 assert!(files.iter().any(|f| f == "app.js"));
71 assert!(files.iter().any(|f| f == "styles.css"));
72 assert!(files.iter().any(|f| f == "graph.js"));
73 assert!(files.iter().any(|f| f == "lsp-client.js"));
74 }
75}