allow using zip as source directly

This commit is contained in:
Robin Appelman 2023-12-21 18:04:23 +01:00
commit 6e2ae0f1a4
4 changed files with 46 additions and 260 deletions

View file

@ -14,9 +14,9 @@ pub enum LoaderError {
Tf2NotFound,
#[error(transparent)]
Io(#[from] std::io::Error),
#[cfg(feature = "zip-lzma")]
#[cfg(feature = "zip")]
#[error(transparent)]
Zip(#[from] zip_lzma::result::ZipError),
Zip(#[from] zip::result::ZipError),
#[error("{0}")]
Other(String),
}

View file

@ -44,7 +44,7 @@ mod vdf {
}
}
#[cfg(feature = "vbsp")]
#[cfg(feature = "bsp")]
mod vbsp {
use super::AssetSource;
use crate::LoaderError;
@ -68,3 +68,43 @@ mod vbsp {
}
}
}
#[cfg(feature = "zip")]
mod zip {
use super::AssetSource;
use crate::LoaderError;
use std::io::{Read, Seek};
use std::sync::Mutex;
use zip::result::ZipError;
use zip::ZipArchive;
impl<Reader: Read + Seek> AssetSource for Mutex<ZipArchive<Reader>> {
fn has(&self, path: &str) -> Result<bool, LoaderError> {
match self.lock().unwrap().by_name(path) {
Ok(_) => Ok(true),
Err(ZipError::FileNotFound) => {
return Ok(false);
}
Err(e) => {
return Err(e.into());
}
}
}
fn load(&self, path: &str) -> Result<Option<Vec<u8>>, LoaderError> {
let mut zip = self.lock().unwrap();
let mut entry = match zip.by_name(path) {
Ok(entry) => entry,
Err(ZipError::FileNotFound) => {
return Ok(None);
}
Err(e) => {
return Err(e.into());
}
};
let mut buff = vec![0; entry.size() as usize];
entry.read_exact(&mut buff)?;
Ok(Some(buff))
}
}
}