diff options
Diffstat (limited to 'src/label.rs')
-rw-r--r-- | src/label.rs | 59 |
1 files changed, 48 insertions, 11 deletions
diff --git a/src/label.rs b/src/label.rs index 7ee55d1..64be341 100644 --- a/src/label.rs +++ b/src/label.rs @@ -6,7 +6,9 @@ //! small number of carefully chosen algorithms are supported here. use sha2::{Digest, Sha256}; -use std::fmt; + +const LITERAL: char = '0'; +const SHA256: char = '1'; /// A checksum of some data. #[derive(Debug, Clone)] @@ -32,18 +34,53 @@ impl Label { Self::Sha256(format!("{:x}", hash)) } - /// Create a `Checksum` from a known, previously computed hash. - pub fn sha256_from_str_unchecked(hash: &str) -> Self { - Self::Sha256(hash.to_string()) + /// 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), + } } -} -impl fmt::Display for Label { - /// Format a checksum for display. - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Literal(s) => write!(f, "{}", s), - Self::Sha256(hash) => write!(f, "{}", hash), + /// De-serialize a label from its string representation. + pub fn deserialize(s: &str) -> Result<Self, LabelError> { + if s.starts_with(LITERAL) { + Ok(Self::Literal(s[1..].to_string())) + } else if s.starts_with(SHA256) { + Ok(Self::Sha256(s[1..].to_string())) + } else { + Err(LabelError::UnknownType(s.to_string())) } } } + +/// Possible errors from dealing with chunk labels. +#[derive(Debug, thiserror::Error)] +pub enum LabelError { + /// Serialized label didn't start with a known type prefix. + #[error("Unknown label: {0:?}")] + UnknownType(String), +} + +#[cfg(test)] +mod test { + use super::Label; + + #[test] + fn roundtrip_literal() { + let label = Label::literal("dummy data"); + let serialized = label.serialize(); + let de = Label::deserialize(&serialized).unwrap(); + let seri2 = de.serialize(); + assert_eq!(serialized, seri2); + } + + #[test] + fn roundtrip_sha256() { + let label = Label::sha256(b"dummy data"); + let serialized = label.serialize(); + let de = Label::deserialize(&serialized).unwrap(); + let seri2 = de.serialize(); + assert_eq!(serialized, seri2); + } +} |