diff options
Diffstat (limited to 'src/label.rs')
-rw-r--r-- | src/label.rs | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/src/label.rs b/src/label.rs index 64be341..19d270a 100644 --- a/src/label.rs +++ b/src/label.rs @@ -5,10 +5,12 @@ //! does not aim to make these algorithms configurable, so only a very //! small number of carefully chosen algorithms are supported here. +use blake2::Blake2s256; use sha2::{Digest, Sha256}; const LITERAL: char = '0'; const SHA256: char = '1'; +const BLAKE2: char = '2'; /// A checksum of some data. #[derive(Debug, Clone)] @@ -18,6 +20,9 @@ pub enum Label { /// A SHA256 checksum. Sha256(String), + + /// A BLAKE2s checksum. + Blake2(String), } impl Label { @@ -34,11 +39,20 @@ impl Label { Self::Sha256(format!("{:x}", hash)) } + /// Compute a BLAKE2s checksum for a block of data. + pub fn blake2(data: &[u8]) -> Self { + let mut hasher = Blake2s256::new(); + hasher.update(data); + let hash = hasher.finalize(); + Self::Sha256(format!("{:x}", hash)) + } + /// Serialize a label into a string representation. pub fn serialize(&self) -> String { match self { Self::Literal(s) => format!("{}{}", LITERAL, s), Self::Sha256(hash) => format!("{}{}", SHA256, hash), + Self::Blake2(hash) => format!("{}{}", BLAKE2, hash), } } @@ -54,6 +68,37 @@ impl Label { } } +/// Kinds of checksum labels. +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub enum LabelChecksumKind { + /// Use a Blake2 checksum. + Blake2, + + /// Use a SHA256 checksum. + Sha256, +} + +impl LabelChecksumKind { + /// Parse a string into a label checksum kind. + pub fn from(s: &str) -> Result<Self, LabelError> { + if s == "sha256" { + Ok(Self::Sha256) + } else if s == "blake2" { + Ok(Self::Blake2) + } else { + Err(LabelError::UnknownType(s.to_string())) + } + } + + /// Serialize a checksum kind into a string. + pub fn serialize(self) -> &'static str { + match self { + Self::Sha256 => "sha256", + Self::Blake2 => "blake2", + } + } +} + /// Possible errors from dealing with chunk labels. #[derive(Debug, thiserror::Error)] pub enum LabelError { @@ -64,7 +109,7 @@ pub enum LabelError { #[cfg(test)] mod test { - use super::Label; + use super::{Label, LabelChecksumKind}; #[test] fn roundtrip_literal() { @@ -83,4 +128,11 @@ mod test { let seri2 = de.serialize(); assert_eq!(serialized, seri2); } + + #[test] + fn roundtrip_checksum_kind() { + for kind in [LabelChecksumKind::Sha256, LabelChecksumKind::Blake2] { + assert_eq!(LabelChecksumKind::from(kind.serialize()).unwrap(), kind); + } + } } |