Address can also refer to an Attribute (String)

feat/vaults
Tomáš Mládek 2021-03-14 12:41:38 +01:00
parent 21e7ee7538
commit 6f31ef5e15
1 changed files with 28 additions and 7 deletions

View File

@ -2,7 +2,6 @@ use crate::hash::{decode, encode, Hash};
use anyhow::{anyhow, Result};
use serde::de::Visitor;
use serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer};
use std::convert::TryInto;
use std::fmt;
use std::io::prelude::*;
use std::io::Cursor;
@ -15,6 +14,7 @@ use uuid::Uuid;
pub enum Address {
Hash(Hash),
UUID(Uuid),
Attribute(String),
}
// multihash KangarooTwelve
@ -27,7 +27,8 @@ impl Address {
pub fn encode(&self) -> Result<Vec<u8>> {
let (hash_func_type, digest) = match self {
Self::Hash(hash) => (KANGAROO_TWELVE, hash.0.clone()),
Self::UUID(uuid) => (IDENTITY, uuid.as_bytes().to_vec()),
Self::UUID(uuid) => (IDENTITY, [vec![b'U'], uuid.as_bytes().to_vec()].concat()),
Self::Attribute(attribute) => (IDENTITY, [&[b'A'], attribute.as_bytes()].concat()),
};
let mut result = Cursor::new(vec![0u8; 0]);
@ -41,7 +42,7 @@ impl Address {
pub fn decode(buffer: &[u8]) -> Result<Self> {
let (hash_func_type, rest) = unsigned_varint::decode::u128(buffer)?;
let (digest_len, rest) = unsigned_varint::decode::usize(rest)?;
let digest = rest;
let digest = rest.to_vec();
if digest_len != digest.len() {
Err(anyhow!(format!(
"Actual digest length ({}) does not match declared digest length ({}).",
@ -50,10 +51,17 @@ impl Address {
)))
} else {
match hash_func_type {
KANGAROO_TWELVE => Ok(Self::Hash(Hash(Vec::from(digest)))),
IDENTITY => Ok(Self::UUID(uuid::Uuid::from_bytes(
TryInto::<[u8; 16]>::try_into(digest).unwrap(),
))),
KANGAROO_TWELVE => Ok(Self::Hash(Hash(digest))),
IDENTITY => {
let digest_content: Vec<u8> = digest.clone().into_iter().skip(1).collect();
match digest[0] {
b'U' => Ok(Self::UUID(uuid::Uuid::from_slice(
digest_content.as_slice(),
)?)),
b'A' => Ok(Self::Attribute(String::from_utf8(digest_content)?)),
_ => Err(anyhow!("Unknown identity marker.")),
}
}
_ => Err(anyhow!("Unknown hash function type.")),
}
}
@ -148,4 +156,17 @@ mod tests {
assert_eq!(format!("{}", addr), format!("{}", decoded.unwrap()));
}
#[test]
fn test_attribute_codec() {
let addr = Address::Attribute(String::from("ATTRIBUTE"));
let encoded = addr.encode();
assert!(encoded.is_ok());
let decoded = Address::decode(&encoded.unwrap());
assert!(decoded.is_ok());
assert_eq!(format!("{}", addr), format!("{}", decoded.unwrap()));
}
}