use std::{borrow::Cow, fs::File, num::ParseIntError, path::Path, str::Utf8Error};
use thiserror::Error;
#[cfg(not(feature = "native-impl"))]
pub mod head_libclamav;
#[cfg(feature = "native-impl")]
pub mod head_native;
#[cfg(not(feature = "native-impl"))]
pub use head_libclamav::Header;
#[cfg(feature = "native-impl")]
pub use head_native::Header;
pub trait Meta {
fn from_header_bytes(bytes: &[u8; 512]) -> Result<Self, HeadError>
where
Self: Sized;
fn from_file(fh: &mut File) -> Result<Self, HeadError>
where
Self: Sized,
{
use std::io::Read;
let mut buf = [0u8; 512];
fh.read_exact(buf.as_mut_slice())?;
Self::from_header_bytes(&buf)
}
fn from_path(path: &Path) -> Result<Self, HeadError>
where
Self: Sized,
{
let mut fh = File::open(path)?;
Self::from_file(&mut fh)
}
fn f_level(&self) -> usize;
fn n_sigs(&self) -> usize;
fn time_str(&self) -> Cow<'_, str>;
fn version(&self) -> usize;
fn md5_str(&self) -> Cow<'_, str>;
fn dsig_str(&self) -> Cow<'_, str>;
fn builder(&self) -> Cow<'_, str>;
fn stime(&self) -> u64;
}
#[derive(Debug, Error)]
pub enum HeadError {
#[error("unable to parse (see log output)")]
Parse,
#[error("IO Error: {0}")]
Io(#[from] std::io::Error),
#[error("bad magic")]
BadMagic,
#[error("missing creation time field")]
MissingCreationTime,
#[error("missing version field")]
MissingVersion,
#[error("missing number of signatures field")]
MissingNumberOfSigs,
#[error("missing f_level field")]
MissingFLevel,
#[error("missing md5 field")]
MissingMd5,
#[error("missing dsig field")]
MissingDSig,
#[error("missing builder field")]
MissingBuilder,
#[error("non-UTF-8 contenti: {0}")]
Utf8(#[from] Utf8Error),
#[error("unable to parse integer: {0}")]
ParseInt(#[from] ParseIntError),
#[error("unable to parse time: {0}")]
ParseTime(#[from] time::error::Parse),
#[error("value of stime would overflow SystemTime")]
STimeTooLarge,
}