use sodiumoxide::crypto::hash::sha256::Digest;
pub type SdName = Digest;
pub type LinkDescriptor = [u8; 32];
#[allow(missing_docs)]
#[derive(RustcEncodable, RustcDecodable, PartialEq, Debug, Clone)]
pub enum BlockIdentifier {
ImmutableData(Digest),
StructuredData(Digest, SdName),
Link(LinkDescriptor), }
impl BlockIdentifier {
pub fn hash(&self) -> Digest {
match *self {
BlockIdentifier::ImmutableData(hash) => hash,
BlockIdentifier::StructuredData(hash, _name) => hash,
BlockIdentifier::Link(hash) => Digest(hash),
}
}
pub fn structured_data_name(&self) -> Option<SdName> {
match *self {
BlockIdentifier::ImmutableData(_hash) => None,
BlockIdentifier::StructuredData(_hash, name) => Some(name),
BlockIdentifier::Link(_hash) => None,
}
}
pub fn is_link(&self) -> bool {
match *self {
BlockIdentifier::ImmutableData(_) |
BlockIdentifier::StructuredData(_, _) => false,
BlockIdentifier::Link(_) => true,
}
}
pub fn is_block(&self) -> bool {
!self.is_link()
}
}
#[cfg(test)]
mod tests {
use super::*;
use sodiumoxide::crypto::hash::sha256;
#[test]
fn create_validate_link_identifier() {
::sodiumoxide::init();
let link = BlockIdentifier::Link(sha256::hash(b"1").0);
assert!(link.is_link());
assert!(!link.is_block());
assert!(link.structured_data_name().is_none());
}
#[test]
fn create_validate_immutable_data_identifier() {
let id_block = BlockIdentifier::ImmutableData(sha256::hash(b"1"));
assert!(!id_block.is_link());
assert!(id_block.is_block());
assert_eq!(id_block.hash(), sha256::hash("1".as_bytes()));
assert!(id_block.structured_data_name().is_none());
}
#[test]
fn create_validate_structured_data_identifier() {
let sd_block = BlockIdentifier::StructuredData(sha256::hash(b"hash"),
sha256::hash(b"name"));
assert!(!sd_block.is_link());
assert!(sd_block.is_block());
assert_eq!(sd_block.hash(), sha256::hash("hash".as_bytes()));
assert!(sd_block.structured_data_name().is_some());
assert_eq!(sd_block.structured_data_name().expect("sd name"),
sha256::hash("name".as_bytes()))
}
}