use crate::BaleError;
use std::fs::File;
use std::path::Path;
pub struct MappedArchive {
file: File,
mmap: memmap2::Mmap,
}
impl MappedArchive {
pub fn open(path: impl AsRef<Path>) -> Result<Self, BaleError> {
let file = File::open(path.as_ref())?;
file.lock_shared()?;
#[allow(unsafe_code)]
let mmap = unsafe { memmap2::Mmap::map(&file)? };
Ok(Self { file, mmap })
}
#[must_use]
pub fn len(&self) -> usize {
self.mmap.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.mmap.is_empty()
}
#[must_use]
pub fn as_bytes(&self) -> &[u8] {
&self.mmap
}
#[must_use]
pub fn file(&self) -> &File {
&self.file
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::io::Write;
use tempfile::NamedTempFile;
#[test]
fn open_valid_file() {
let mut file = NamedTempFile::new().unwrap();
file.write_all(b"test data").unwrap();
let mapped = MappedArchive::open(file.path()).unwrap();
assert_eq!(mapped.len(), 9);
assert_eq!(mapped.as_bytes(), b"test data");
}
#[test]
fn open_nonexistent_file() {
let result = MappedArchive::open("/nonexistent/path/to/file.bale");
assert!(result.is_err());
}
#[test]
fn open_empty_file() {
let file = NamedTempFile::new().unwrap();
let mapped = MappedArchive::open(file.path()).unwrap();
assert!(mapped.is_empty());
assert_eq!(mapped.len(), 0);
}
}