149 lines
3.5 KiB
Rust
149 lines
3.5 KiB
Rust
use super::templates::HyperlegibleTemplate;
|
|
use askama::Template;
|
|
use rocket::http::Status;
|
|
use rust_embed::RustEmbed;
|
|
use sha2::{Digest, Sha256};
|
|
use std::{borrow::Cow, sync::OnceLock};
|
|
|
|
#[derive(RustEmbed)]
|
|
#[folder = "public/"]
|
|
struct Assets;
|
|
|
|
#[derive(Debug)]
|
|
pub struct Files {
|
|
pub style: TextFile,
|
|
pub hyperlegible: TextFile,
|
|
pub atkinson_latin_woff2: BinaryFile,
|
|
pub atkinson_latin_ext_woff2: BinaryFile,
|
|
pub atkinson_all_woff: BinaryFile,
|
|
}
|
|
|
|
#[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,
|
|
}
|
|
|
|
trait GetFile {
|
|
fn get(filename: &str, extension: &str) -> Option<Self>
|
|
where
|
|
Self: Sized;
|
|
}
|
|
|
|
impl GetFile for BinaryFile {
|
|
fn get(filename: &str, extension: &str) -> Option<Self> {
|
|
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,
|
|
})
|
|
}
|
|
None => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl GetFile for TextFile {
|
|
fn get(filename: &str, extension: &str) -> Option<Self> {
|
|
let file = BinaryFile::get(filename, extension)?;
|
|
match std::str::from_utf8(&file.data) {
|
|
Ok(string) => Some(TextFile {
|
|
text: string.into(),
|
|
metadata: file.metadata,
|
|
}),
|
|
Err(_) => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub static FILES: OnceLock<Files> = OnceLock::new();
|
|
|
|
pub fn get_file_wrapper() -> Result<&'static Files, Status> {
|
|
match FILES.get() {
|
|
Some(files) => Ok(files),
|
|
None => Err(Status::InternalServerError),
|
|
}
|
|
}
|
|
|
|
fn get_sha256_hash(string: &String) -> String {
|
|
let mut hasher = Sha256::new();
|
|
hasher.update(string);
|
|
let result = hasher.finalize();
|
|
hex::encode(result)
|
|
}
|
|
|
|
fn get_hyperlegible(
|
|
latin_woff2_filename: String,
|
|
latin_ext_woff2_filename: String,
|
|
all_woff_filename: String,
|
|
) -> TextFile {
|
|
let hyperlegible_template = HyperlegibleTemplate {
|
|
atkinson_latin_woff2_filename: latin_woff2_filename,
|
|
atkinson_latin_ext_woff2_filename: latin_ext_woff2_filename,
|
|
atkinson_all_woff_filename: all_woff_filename,
|
|
};
|
|
|
|
let rendered_template = hyperlegible_template.render().unwrap();
|
|
let hash = get_sha256_hash(&rendered_template);
|
|
|
|
let metadata = FileMetadata {
|
|
filename: "hyperlegible".into(),
|
|
extension: "css".into(),
|
|
hash,
|
|
};
|
|
|
|
TextFile {
|
|
text: rendered_template,
|
|
metadata,
|
|
}
|
|
}
|
|
|
|
pub fn initialize_files() {
|
|
let atkinson_latin_woff2 =
|
|
BinaryFile::get("atkinson-hyperlegible-latin-400-normal", "woff2").unwrap();
|
|
let atkinson_latin_ext_woff2 =
|
|
BinaryFile::get("atkinson-hyperlegible-latin-ext-400-normal", "woff2").unwrap();
|
|
let atkinson_all_woff =
|
|
BinaryFile::get("atkinson-hyperlegible-all-400-normal", "woff").unwrap();
|
|
|
|
let files = Files {
|
|
style: TextFile::get("style", "css").unwrap(),
|
|
hyperlegible: get_hyperlegible(
|
|
atkinson_latin_woff2.metadata.get_hash_filename(),
|
|
atkinson_latin_ext_woff2.metadata.get_hash_filename(),
|
|
atkinson_all_woff.metadata.get_hash_filename(),
|
|
),
|
|
atkinson_latin_woff2,
|
|
atkinson_latin_ext_woff2,
|
|
atkinson_all_woff,
|
|
};
|
|
FILES.set(files).unwrap();
|
|
}
|