use std::path::Path;
use crate::error::Error;
#[derive(Clone, Copy, Debug)]
pub struct Source<'a> {
pub path: &'a Path,
pub member: Option<&'a str>,
}
impl<'a> Source<'a> {
#[must_use]
pub fn new(path: &'a Path) -> Self {
Self { path, member: None }
}
#[must_use]
pub fn member(path: &'a Path, member: &'a str) -> Self {
Self {
path,
member: Some(member),
}
}
#[cold]
#[inline(never)]
#[must_use]
pub fn malformed(&self, offset: u64, what: impl Into<String>) -> Error {
Error::Malformed {
file: self.path.to_path_buf(),
member: self.member.map(str::to_owned),
offset,
what: what.into(),
}
}
}
#[inline]
pub(crate) fn subslice(data: &[u8], offset: u64, size: u64) -> Option<&[u8]> {
let start = usize::try_from(offset).ok()?;
let len = usize::try_from(size).ok()?;
let end = start.checked_add(len)?;
data.get(start..end)
}
#[inline]
pub(crate) fn to_u64(value: usize) -> u64 {
u64::try_from(value).unwrap_or(u64::MAX)
}
#[inline]
pub(crate) fn entry_offset(base: u64, index: usize, size: usize) -> u64 {
base.saturating_add(to_u64(index).saturating_mul(to_u64(size)))
}