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 { 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(reader: &mut T) -> Result { 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(&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(()) } }