use bytes::Bytes;
use http_body_util::{BodyExt, Full, combinators::BoxBody};
use hyper::{Response, StatusCode};
type ApiBody = BoxBody<Bytes, std::convert::Infallible>;
pub struct Asset {
pub route: &'static str,
pub content_type: &'static str,
pub etag: &'static str,
pub no_cache: bool,
pub gz: &'static [u8],
}
static ASSETS: &[Asset] = include!(concat!(env!("OUT_DIR"), "/webui_assets.rs"));
pub fn serve(path: &str) -> Option<Response<ApiBody>> {
let asset = ASSETS.iter().find(|a| a.route == path)?;
let cache_control = if asset.no_cache {
"no-cache"
} else {
"public, max-age=31536000, immutable"
};
Some(
Response::builder()
.status(StatusCode::OK)
.header(hyper::header::CONTENT_TYPE, asset.content_type)
.header(hyper::header::CONTENT_ENCODING, "gzip")
.header(hyper::header::CACHE_CONTROL, cache_control)
.header(hyper::header::ETAG, format!("\"{}\"", asset.etag))
.body(Full::new(Bytes::from_static(asset.gz)).boxed())
.expect("resposta estática bem-formada"),
)
}
#[cfg(test)]
mod headless_tests;
#[cfg(test)]
#[test]
fn toda_tela_que_usa_t_importa_o_t() {
let dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("webui/screens");
for entry in std::fs::read_dir(&dir).unwrap() {
let path = entry.unwrap().path();
if path.extension().and_then(|e| e.to_str()) != Some("js") {
continue;
}
let src = std::fs::read_to_string(&path).unwrap();
let usa_t = src.lines().any(|l| {
let l = l.trim_start();
if l.starts_with("//") || l.starts_with('*') || l.starts_with("/*") {
return false;
}
let bytes = l.as_bytes();
(0..bytes.len().saturating_sub(1)).any(|i| {
bytes[i] == b't'
&& (bytes[i + 1] == b'(' || bytes[i + 1] == b'`')
&& (i == 0
|| !(bytes[i - 1].is_ascii_alphanumeric()
|| bytes[i - 1] == b'_'
|| bytes[i - 1] == b'.'
|| bytes[i - 1] == b'$'))
})
});
let importa = src.contains("from \"../i18n.js\"");
assert!(
!usa_t || importa,
"{} usa t(...) mas não importa o t de ../i18n.js",
path.display()
);
}
}