use super::http::{IMMUTABLE, Packed, REVALIDATE};
use std::sync::LazyLock;
const INDEX: &[u8] = include_bytes!("assets/rmux-share/index.html");
const CSS: &[u8] = include_bytes!("assets/rmux-share/_astro/index.D2bSaP4U.css");
const JS: &[u8] = include_bytes!(
"assets/rmux-share/_astro/index.astro_astro_type_script_index_0_lang.CdYCpIGm.js"
);
const WASM: &[u8] =
include_bytes!("assets/rmux-share/_astro/rmux_web_crypto_wasm_bg.C8R0tHIf.wasm");
const EMPTY_SVG: &[u8] = b"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1\" height=\"1\"/>";
static INDEX_P: LazyLock<Packed> = LazyLock::new(|| Packed::new(INDEX));
static CSS_P: LazyLock<Packed> = LazyLock::new(|| Packed::new(CSS));
static JS_P: LazyLock<Packed> = LazyLock::new(|| Packed::new(JS));
static WASM_P: LazyLock<Packed> = LazyLock::new(|| Packed::new(WASM));
static EMPTY_P: LazyLock<Packed> = LazyLock::new(|| Packed::new(EMPTY_SVG));
pub struct File {
pub content_type: &'static str,
pub body: &'static Packed,
pub cache: &'static str,
}
pub fn file(path: &str) -> Option<File> {
let (content_type, body, cache): (_, &'static Packed, _) = match path {
"/term" | "/term/" => ("text/html; charset=utf-8", &INDEX_P, REVALIDATE),
"/_astro/index.D2bSaP4U.css" => ("text/css; charset=utf-8", &CSS_P, IMMUTABLE),
"/_astro/index.astro_astro_type_script_index_0_lang.CdYCpIGm.js" => {
("application/javascript; charset=utf-8", &JS_P, IMMUTABLE)
}
"/_astro/rmux_web_crypto_wasm_bg.C8R0tHIf.wasm" => ("application/wasm", &WASM_P, IMMUTABLE),
"/rose-dark.svg" | "/rose-light.svg" => ("image/svg+xml", &EMPTY_P, IMMUTABLE),
_ if is_crab(path) => ("image/svg+xml", &EMPTY_P, IMMUTABLE),
_ => return None,
};
Some(File {
content_type,
body,
cache,
})
}
fn is_crab(path: &str) -> bool {
path.strip_prefix("/term/crabs/")
.and_then(|name| {
name.strip_suffix("-dark.svg")
.or_else(|| name.strip_suffix("-light.svg"))
})
.is_some_and(|colour| !colour.is_empty() && colour.bytes().all(|b| b.is_ascii_lowercase()))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn every_asset_the_page_names_is_served() {
let page = std::str::from_utf8(INDEX).expect("utf-8");
let mut named = 0;
for piece in page.split('"') {
if piece.starts_with("/_astro/") {
assert!(file(piece).is_some(), "{piece} is named but not served");
named += 1;
}
}
assert_eq!(
named, 2,
"the page should name one stylesheet and one script"
);
let js = std::str::from_utf8(JS).expect("utf-8");
assert!(
js.contains("/_astro/rmux_web_crypto_wasm_bg.C8R0tHIf.wasm"),
"the script loads a WebAssembly module this does not serve"
);
assert!(file("/_astro/../index.html").is_none());
}
#[test]
fn every_crab_is_answered_and_nothing_else_is() {
let js = std::str::from_utf8(JS).expect("utf-8");
assert!(
js.contains("crabs/${e}-dark.svg"),
"the app no longer asks for its crabs where this answers them"
);
for colour in ["lime", "indigo", "orange", "green", "blue", "rose"] {
for theme in ["dark", "light"] {
let path = format!("/term/crabs/{colour}-{theme}.svg");
assert!(file(&path).is_some(), "{path} is not answered");
}
}
for not in [
"/term/crabs/-dark.svg",
"/term/crabs/../x-dark.svg",
"/term/crabs/lime-dark.png",
"/term/crabs/Lime-dark.svg",
"/crabs/lime-dark.svg",
] {
assert!(file(not).is_none(), "{not} should not be answered");
}
}
#[test]
fn only_the_hashed_files_are_kept_without_asking() {
assert_eq!(file("/term/").unwrap().cache, REVALIDATE);
for piece in std::str::from_utf8(INDEX).unwrap().split('"') {
if piece.starts_with("/_astro/") {
assert_eq!(file(piece).unwrap().cache, IMMUTABLE, "{piece}");
}
}
}
}