use axum::{
http::{header, StatusCode, Uri},
response::{IntoResponse, Response},
};
use rust_embed::RustEmbed;
#[derive(RustEmbed)]
#[folder = "../../webui/dist/"]
pub struct WebuiAssets;
pub fn asset_or_index(path: &str) -> Option<std::borrow::Cow<'static, [u8]>> {
let p = path.trim_start_matches('/');
if let Some(f) = WebuiAssets::get(p) {
return Some(f.data);
}
WebuiAssets::get("index.html").map(|f| f.data)
}
pub async fn serve_webui(uri: Uri) -> Response {
if let Ok(dev) = std::env::var("ATOMCODE_WEBUI_DEV") {
let target = format!("{}{}", dev.trim_end_matches('/'), uri.path());
return axum::response::Redirect::temporary(&target).into_response();
}
let path = uri.path();
let p = path.trim_start_matches('/');
let lookup = if p.is_empty() { "index.html" } else { p };
match WebuiAssets::get(lookup) {
Some(content) => {
let mime = mime_guess::from_path(lookup).first_or_octet_stream();
([(header::CONTENT_TYPE, mime.as_ref())], content.data).into_response()
}
None => match WebuiAssets::get("index.html") {
Some(index) => ([(header::CONTENT_TYPE, "text/html")], index.data).into_response(),
None => (StatusCode::NOT_FOUND, "webui not built").into_response(),
},
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn serves_embedded_index() {
assert!(WebuiAssets::get("index.html").is_some(), "index.html should be embedded");
}
#[test]
fn unknown_path_falls_back_to_index() {
assert!(asset_or_index("some/spa/route").is_some(), "SPA route should fall back to index");
}
}