use memmap2::Mmap;
use std::{fs::File, io, path::Path};
pub struct MmapFasta {
mmap: Mmap,
}
impl MmapFasta {
#[allow(unsafe_code)]
pub fn open<P: AsRef<Path>>(path: P) -> io::Result<Self> {
let file = File::open(path)?;
let mmap = unsafe { Mmap::map(&file)? };
Ok(Self { mmap })
}
pub fn as_bytes(&self) -> &[u8] {
&self.mmap
}
pub fn len(&self) -> usize {
self.mmap.len()
}
pub fn is_empty(&self) -> bool {
self.mmap.is_empty()
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use super::*;
use std::io::Write;
use tempfile::NamedTempFile;
#[test]
fn mmap_fasta_open_and_read() {
let mut temp = NamedTempFile::new().unwrap();
writeln!(temp, ">seq1").unwrap();
writeln!(temp, "ACGT").unwrap();
temp.flush().unwrap();
let mmap = MmapFasta::open(temp.path()).unwrap();
assert!(!mmap.is_empty());
assert!(mmap.as_bytes().starts_with(b">seq1"));
}
#[test]
fn mmap_fasta_len() {
let mut temp = NamedTempFile::new().unwrap();
write!(temp, "ACGT").unwrap();
temp.flush().unwrap();
let mmap = MmapFasta::open(temp.path()).unwrap();
assert_eq!(mmap.len(), 4);
}
}