summaryrefslogtreecommitdiff
path: root/src/label.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/label.rs')
-rw-r--r--src/label.rs54
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);
+ }
+ }
}