haggis-rs/src/checksum.rs
2023-07-06 18:31:49 -04:00

87 lines
2.4 KiB
Rust

use {
crate::Error,
std::{io::{Read, Write}, str::FromStr},
};
#[derive(Clone, Copy, Debug)]
pub enum Algorithm {
Md5,
Sha1,
Sha256,
Skip,
}
impl FromStr for Algorithm {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"md5" | "Md5" => Ok(Self::Md5),
"sha1" | "Sha1" => Ok(Self::Sha1),
"sha256" | "Sha256" => Ok(Self::Sha256),
"skip" | "Skip" => Ok(Self::Skip),
_ => Err(Error::InvalidAlgorithm),
}
}
}
/// Optional checksumming for individual files
#[derive(Debug)]
pub enum Checksum {
/// Md5 checksumming, fastest
Md5([u8; 16]),
/// Sha1 checksumming. On par with md5.
Sha1([u8; 20]),
/// The most thorough checksumming offered. Use this if data integrity is of
/// utmost importance and computational overhead is of lesser importance.
Sha256([u8; 32]),
/// Do not use checksumming. If this option is selected it is recommended that
/// the entire archive is downloaded in entirety and checksummed to ensure it's
/// integrity, as was the pattern with Unix 'tar' archives and 'iso' images
Skip,
}
impl Checksum {
pub(crate) fn read<T: Read>(reader: &mut T) -> Result<Self, Error> {
let mut buf = [0; 1];
reader.read_exact(&mut buf)?;
match buf[0] {
0 => {
let mut sum = [0; 16];
reader.read_exact(&mut sum)?;
Ok(Self::Md5(sum))
}
1 => {
let mut sum = [0; 20];
reader.read_exact(&mut sum)?;
Ok(Self::Sha1(sum))
}
2 => {
let mut sum = [0; 32];
reader.read_exact(&mut sum)?;
Ok(Self::Sha256(sum))
}
_ => Ok(Self::Skip),
}
}
pub(crate) fn write<T: Write>(&self, writer: &mut T) -> Result<(), Error> {
match self {
Self::Md5(sum) => {
writer.write_all(&[b'0'])?;
writer.write_all(&sum[..])?;
}
Self::Sha1(sum) => {
writer.write_all(&[b'1'])?;
writer.write_all(&sum[..])?;
}
Self::Sha256(sum) => {
writer.write_all(&[b'2'])?;
writer.write_all(&sum[..])?;
}
Self::Skip => writer.write_all(&[b'3'])?,
}
Ok(())
}
}