use rocket::http::Status; use rust_embed::RustEmbed; use std::{borrow::Cow, sync::OnceLock}; #[derive(RustEmbed)] #[folder = "public/"] struct Assets; #[derive(Debug)] pub struct Files { pub atkinson_latin_woff2: BinaryFile, pub atkinson_latin_ext_woff2: BinaryFile, pub atkinson_all_woff: BinaryFile, pub style: TextFile, pub hyperlegible: TextFile, } #[derive(Debug, Clone)] pub struct FileMetadata { pub filename: String, pub extension: String, pub hash: String, } impl FileMetadata { pub fn get_hash_filename(&self) -> String { let mut hash = self.hash.clone(); hash.truncate(8); format!("{}.{}.{}", self.filename, hash, self.extension) } } #[derive(Debug)] pub struct BinaryFile { pub data: Cow<'static, [u8]>, pub metadata: FileMetadata, } #[derive(Debug, Clone)] pub struct TextFile { pub text: String, pub metadata: FileMetadata, } pub static FILES: OnceLock = OnceLock::new(); pub fn get_file_wrapper() -> Result<&'static Files, Status> { match FILES.get() { Some(files) => Ok(files), None => Err(Status::InternalServerError), } } fn get_binary_file(filename: &str, extension: &str) -> Option { match Assets::get(&format!("{}.{}", filename, extension)) { Some(file) => { let metadata = FileMetadata { filename: filename.into(), extension: extension.into(), hash: hex::encode(file.metadata.sha256_hash()), }; Some(BinaryFile { data: file.data, metadata: metadata, }) } None => None, } } fn get_text_file(filename: &str, extension: &str) -> Option { let file = get_binary_file(filename, extension)?; match std::str::from_utf8(&file.data) { Ok(string) => Some(TextFile { text: string.into(), metadata: file.metadata, }), Err(_) => None, } } pub fn initialize_files() { let files = Files { atkinson_latin_woff2: get_binary_file("atkinson-hyperlegible-latin-400-normal", "woff2") .unwrap(), atkinson_latin_ext_woff2: get_binary_file( "atkinson-hyperlegible-latin-ext-400-normal", "woff2", ) .unwrap(), atkinson_all_woff: get_binary_file("atkinson-hyperlegible-all-400-normal", "woff").unwrap(), style: get_text_file("style", "css").unwrap(), hyperlegible: get_text_file("hyperlegible", "css").unwrap(), }; FILES.set(files).unwrap(); }