mod md5;
mod sha1;
mod sha256;
use core::fmt;
use std::io;
pub use md5::MD5;
pub use sha1::Sha1;
pub use sha256::Sha256;
use zerocopy::LE;
use crate::read::ReadBytesExt;
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Checksum {
Adler32(u32),
Crc32(u32),
MD5(MD5),
Sha1(Sha1),
Sha256(Sha256),
Check([u8; 4]),
}
impl Checksum {
#[must_use]
#[inline]
pub const fn new_md5(md5: [u8; 16]) -> Self {
Self::MD5(MD5::new(md5))
}
#[must_use]
#[inline]
pub const fn new_sha1(sha1: [u8; 20]) -> Self {
Self::Sha1(Sha1::new(sha1))
}
#[must_use]
#[inline]
pub const fn new_sha256(sha256: [u8; 32]) -> Self {
Self::Sha256(Sha256::new(sha256))
}
pub fn read_adler32<R: io::Read>(mut reader: R) -> io::Result<Self> {
reader.read_u32::<LE>().map(Self::Adler32)
}
pub fn read_crc32<R: io::Read>(mut reader: R) -> io::Result<Self> {
reader.read_u32::<LE>().map(Self::Crc32)
}
pub fn read_md5<R: io::Read>(mut reader: R) -> io::Result<Self> {
reader.read_t::<MD5>().map(Self::MD5)
}
pub fn read_sha1<R: io::Read>(mut reader: R) -> io::Result<Self> {
reader.read_t::<Sha1>().map(Self::Sha1)
}
pub fn read_sha256<R: io::Read>(mut reader: R) -> io::Result<Self> {
reader.read_t::<Sha256>().map(Self::Sha256)
}
#[must_use]
#[inline]
pub const fn is_adler32(&self) -> bool {
matches!(self, Self::Adler32(_))
}
#[must_use]
#[inline]
pub const fn is_crc32(&self) -> bool {
matches!(self, Self::Crc32(_))
}
#[must_use]
#[inline]
pub const fn is_md5(&self) -> bool {
matches!(self, Self::MD5(_))
}
#[must_use]
#[inline]
pub const fn is_sha1(&self) -> bool {
matches!(self, Self::Sha1(_))
}
#[must_use]
#[inline]
pub const fn is_sha256(&self) -> bool {
matches!(self, Self::Sha256(_))
}
}
impl fmt::Debug for Checksum {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Adler32(adler32) => f.debug_tuple("Adler32").field(adler32).finish(),
Self::Crc32(crc32) => f.debug_tuple("Crc32").field(crc32).finish(),
Self::MD5(md5) => f.debug_tuple("MD5").field(md5).finish(),
Self::Sha1(sha1) => f.debug_tuple("SHA1").field(sha1).finish(),
Self::Sha256(sha256) => f.debug_tuple("SHA256").field(sha256).finish(),
Self::Check(check) => f.debug_tuple("Check").field(check).finish(),
}
}
}
impl fmt::Display for Checksum {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Adler32(adler32) => write!(f, "{adler32}"),
Self::Crc32(crc32) => write!(f, "{crc32}"),
Self::MD5(md5) => write!(f, "{md5}"),
Self::Sha1(sha1) => write!(f, "{sha1}"),
Self::Sha256(sha256) => write!(f, "{sha256}"),
Self::Check(check) => write!(f, "{:?}", u32::from_le_bytes(*check)),
}
}
}
impl Default for Checksum {
fn default() -> Self {
Self::Adler32(0)
}
}