use std::borrow::Cow;
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct EmbeddedResource {
#[allow(unused)]
pub file_name: &'static str,
pub content_type: &'static str,
pub content: &'static [u8],
}
#[derive(Debug, Default, Clone)]
pub struct EmbeddedResources {
pub data: HashMap<&'static str, EmbeddedResource>,
pub fallback: &'static str,
}
impl EmbeddedResources {
#[must_use]
pub fn with_fallback(fallback: &'static str) -> Self {
Self {
data: HashMap::new(),
fallback,
}
}
#[must_use]
pub fn get(&self, path: &str) -> Option<&EmbeddedResource> {
self.data.get(path).or_else(|| self.data.get(self.fallback))
}
}
#[must_use]
pub fn get_content_type(path: &str) -> &'static str {
let extension = path.rfind('.').map(|index| &path[(index + 1)..]);
match extension {
Some("html") => "text/html",
Some("css") => "text/css",
Some("js") => "text/javascript",
Some("gif") => "image/gif",
Some("png") => "image/png",
Some("jpeg") => "image/jpeg",
Some("bmp") => "image/bmp",
Some("webp") => "image/webp",
Some("svg") => "image/svg+xml",
Some("ico") => "image/x-icon",
_ => "application/octet-stream",
}
}
pub enum WebappResource {
Embedded(EmbeddedResource),
HotReload { content_type: String, data: Vec<u8> },
}
impl WebappResource {
#[must_use]
pub fn content_type(&self) -> &str {
match self {
Self::Embedded(res) => res.content_type,
Self::HotReload { content_type, data: _ } => content_type,
}
}
#[must_use]
pub fn into_data(self) -> Cow<'static, [u8]> {
match self {
Self::Embedded(res) => Cow::Borrowed(res.content),
Self::HotReload { content_type: _, data } => Cow::Owned(data),
}
}
}