use crate::{
io::{is_data_url, Deserialize},
Error, Result,
};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
#[derive(Default)]
pub struct RawAssets(HashMap<PathBuf, Vec<u8>>);
impl RawAssets {
pub fn new() -> Self {
Self::default()
}
pub fn remove(&mut self, path: impl AsRef<Path>) -> Result<Vec<u8>> {
Ok(self.0.remove(&self.match_path(path.as_ref())?).unwrap())
}
pub fn get(&self, path: impl AsRef<Path>) -> Result<&[u8]> {
Ok(self.0.get(&self.match_path(path.as_ref())?).unwrap())
}
pub(crate) fn match_path(&self, path: &Path) -> Result<PathBuf> {
if is_data_url(path) || self.0.contains_key(path) {
Ok(path.into())
} else {
let p = path.to_str().unwrap().replace('\\', "/");
let p = if p.ends_with(".jpeg") {
p[0..p.len() - 2].to_string()
} else if p.ends_with(".jpg") {
p[0..p.len() - 1].to_string()
} else {
p
};
self.0
.iter()
.find(|(k, _)| k.to_str().unwrap().contains(&p))
.map(|(k, _)| k.clone())
.ok_or(Error::NotLoaded(path.to_str().unwrap().to_string()))
}
}
pub fn insert(&mut self, path: impl AsRef<Path>, bytes: Vec<u8>) -> &mut Self {
let key = path.as_ref().to_str().unwrap().replace('\\', "/").into();
self.0.insert(key, bytes);
self
}
pub fn extend(&mut self, mut raw_assets: Self) -> &mut Self {
for (k, v) in raw_assets.0.drain() {
self.insert(k, v);
}
self
}
pub fn deserialize<T: Deserialize>(&mut self, path: impl AsRef<Path>) -> Result<T> {
T::deserialize(path, self)
}
#[cfg_attr(docsrs, doc(not(target_arch = "wasm32")))]
#[cfg(not(target_arch = "wasm32"))]
pub fn save(&mut self) -> Result<()> {
crate::io::save(self)
}
}
impl std::ops::Deref for RawAssets {
type Target = HashMap<PathBuf, Vec<u8>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl std::fmt::Debug for RawAssets {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut d = f.debug_struct("RawAssets");
for (key, value) in self.0.iter() {
d.field("path", key);
d.field("byte length", &value.len());
}
d.finish()
}
}