#![warn(clippy::pedantic)]
use std::{borrow::Cow, collections::HashMap};
use serde::{Deserialize, Serialize};
pub mod parsing;
pub type ViteManifest<'a> = HashMap<Cow<'a, str>, ManifestChunk<'a>>;
#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq, Eq, Hash)]
#[serde(rename_all = "camelCase")]
pub struct ManifestChunk<'a> {
#[serde(skip)]
pub key: Cow<'a, str>,
#[serde(skip)]
pub contents: Cow<'a, [u8]>,
#[serde(skip)]
pub hash: Cow<'a, str>,
#[serde(skip)]
pub mime_type: Cow<'a, str>,
pub src: Option<Cow<'a, str>>,
pub file: Cow<'a, str>,
#[serde(default)]
pub css: Cow<'a, [Cow<'a, str>]>,
#[serde(default)]
pub assets: Cow<'a, [Cow<'a, str>]>,
#[serde(default)]
pub is_entry: bool,
pub name: Option<Cow<'a, str>>,
#[serde(default)]
pub is_dynamic_entry: bool,
#[serde(default)]
pub imports: Cow<'a, [Cow<'a, str>]>,
#[serde(default)]
pub dynamic_imports: Cow<'a, [Cow<'a, str>]>,
}
pub trait Boxed<'a> {
fn boxed(&self) -> Box<dyn Manifest<'a>>;
}
pub trait StaticManifest: Boxed<'static> {
fn static_key_output_pairs(&self) -> &[(&'static str, &'static str)];
fn static_chunks(&self) -> &[(&'static str, &'static ManifestChunk<'static>)];
}
pub trait Manifest<'a>: Boxed<'a> {
fn resolve_output(&self, key: &str) -> Option<Cow<'a, str>>;
fn iter_keys(&self) -> Box<dyn Iterator<Item = &str> + '_>;
fn iter_outputs(&self) -> Box<dyn Iterator<Item = &str> + '_>;
fn chunk(&self, output: &str) -> Option<Cow<'a, ManifestChunk<'a>>>;
fn chunk_by_key(&self, key: &str) -> Option<Cow<'a, ManifestChunk<'a>>> {
match self.resolve_output(key) {
Some(output) => self.chunk(&output),
None => None,
}
}
}
impl<M: StaticManifest> Manifest<'static> for M {
fn resolve_output(&self, key: &str) -> Option<Cow<'static, str>> {
let pairs = self.static_key_output_pairs();
match pairs.binary_search_by_key(&key, |(this_key, _)| this_key) {
Ok(index) => Some(Cow::Borrowed(pairs[index].1)),
Err(_) => None,
}
}
fn iter_keys(&self) -> Box<dyn Iterator<Item = &str> + '_> {
Box::new(self.static_key_output_pairs().iter().map(|&(key, _)| key))
}
fn iter_outputs(&self) -> Box<dyn Iterator<Item = &str> + '_> {
Box::new(
self.static_key_output_pairs()
.iter()
.map(|&(_, output)| output),
)
}
fn chunk(&self, output: &str) -> Option<Cow<'static, ManifestChunk<'static>>> {
let chunks = self.static_chunks();
match chunks.binary_search_by_key(&output, |(this_output, _)| this_output) {
Ok(index) => Some(Cow::Borrowed(chunks[index].1)),
Err(_) => None,
}
}
}