use std::ops::Range;
use std::sync::Arc;
use crate::PslError;
#[cfg(feature = "mmap")]
use memmap2::Mmap;
#[derive(Debug, Clone)]
pub enum SharedBytes {
#[cfg(feature = "mmap")]
Mmap(Arc<Mmap>),
Owned(Arc<Vec<u8>>),
}
impl SharedBytes {
pub fn as_slice(&self) -> &[u8] {
match self {
#[cfg(feature = "mmap")]
SharedBytes::Mmap(m) => &m[..],
SharedBytes::Owned(buf) => buf.as_slice(),
}
}
#[cfg(feature = "mmap")]
pub(crate) fn from_mmap(mmap: Mmap) -> Self {
SharedBytes::Mmap(Arc::new(mmap))
}
pub fn from_owned(data: Vec<u8>) -> Self {
SharedBytes::Owned(Arc::new(data))
}
}
#[derive(Debug, Clone)]
pub struct ByteSlice {
storage: SharedBytes,
range: Range<usize>,
}
impl ByteSlice {
pub fn new(storage: SharedBytes, range: Range<usize>) -> Self {
ByteSlice { storage, range }
}
pub fn as_bytes(&self) -> &[u8] {
&self.storage.as_slice()[self.range.clone()]
}
pub fn as_str(&self) -> Option<&str> {
std::str::from_utf8(self.as_bytes()).ok()
}
pub fn len(&self) -> usize {
self.range.len()
}
pub fn is_empty(&self) -> bool {
self.range.is_empty()
}
}
pub fn is_gz_path(path: &std::path::Path) -> bool {
path.extension().is_some_and(|ext| ext == "gz")
}
#[cfg_attr(feature = "gzip", allow(dead_code))]
pub fn gzip_feature_error() -> PslError {
PslError::Unsupported {
msg: "gzip support disabled; enable the `gzip` feature".into(),
}
}