wip: refactor LargeMultihash out

feat/type-attributes
Tomáš Mládek 2023-06-29 15:10:31 +02:00
parent 57871c2102
commit 0a27931de4
7 changed files with 51 additions and 29 deletions

View File

@ -46,7 +46,7 @@ pub type UpCid = cid::CidGeneric<256>;
impl Address { impl Address {
pub fn encode(&self) -> Result<Vec<u8>, UpEndError> { pub fn encode(&self) -> Result<Vec<u8>, UpEndError> {
let (codec, hash) = match self { let (codec, hash) = match self {
Self::Hash(hash) => (RAW, hash.0), Self::Hash(hash) => (RAW, LargeMultihash::from(hash)),
Self::Uuid(uuid) => ( Self::Uuid(uuid) => (
UP_UUID, UP_UUID,
LargeMultihash::wrap(IDENTITY, uuid.as_bytes()).map_err(UpEndError::from_any)?, LargeMultihash::wrap(IDENTITY, uuid.as_bytes()).map_err(UpEndError::from_any)?,
@ -74,7 +74,7 @@ impl Address {
})?; })?;
if cid.codec() == RAW { if cid.codec() == RAW {
return Ok(Address::Hash(UpMultihash(*cid.hash()))); return Ok(Address::Hash(UpMultihash::from(*cid.hash())));
} }
let hash = cid.hash(); let hash = cid.hash();
@ -109,7 +109,7 @@ impl Address {
pub fn as_components<'a>(&'a self) -> AddressComponents { pub fn as_components<'a>(&'a self) -> AddressComponents {
// TODO: make this automatically derive from `Address` definition // TODO: make this automatically derive from `Address` definition
let (entity_type, entity_content) = match self { let (entity_type, entity_content) = match self {
Address::Hash(uphash) => ("Hash", Some(b58_encode(uphash.0.to_bytes()))), Address::Hash(uphash) => ("Hash", Some(b58_encode(uphash.to_bytes()))),
Address::Uuid(uuid) => ("Uuid", Some(uuid.to_string())), Address::Uuid(uuid) => ("Uuid", Some(uuid.to_string())),
Address::Attribute(attribute) => ("Attribute", Some(attribute.clone())), Address::Attribute(attribute) => ("Attribute", Some(attribute.clone())),
Address::Url(url) => ("Url", Some(url.to_string())), Address::Url(url) => ("Url", Some(url.to_string())),
@ -250,7 +250,7 @@ mod tests {
#[test] #[test]
fn test_hash_codec() -> Result<(), UpEndError> { fn test_hash_codec() -> Result<(), UpEndError> {
let addr = Address::Hash(UpMultihash( let addr = Address::Hash(UpMultihash::from(
LargeMultihash::wrap(IDENTITY, &vec![1, 2, 3, 4, 5]).unwrap(), LargeMultihash::wrap(IDENTITY, &vec![1, 2, 3, 4, 5]).unwrap(),
)); ));
let encoded = addr.encode()?; let encoded = addr.encode()?;

View File

@ -1,6 +1,6 @@
use crate::addressing::Address; use crate::addressing::Address;
use crate::entry::InvariantEntry; use crate::entry::InvariantEntry;
use crate::hash::LargeMultihash; use crate::hash::{LargeMultihash, UpMultihash};
/// Attribute denoting (hierarchical) relation, in the "upwards" direction. For example, a file `IN` a group, an image `IN` photos, etc. /// Attribute denoting (hierarchical) relation, in the "upwards" direction. For example, a file `IN` a group, an image `IN` photos, etc.
pub const ATTR_IN: &str = "IN"; pub const ATTR_IN: &str = "IN";
@ -24,7 +24,7 @@ lazy_static! {
}; };
pub static ref HIER_ROOT_ADDR: Address = HIER_ROOT_INVARIANT.entity().unwrap(); pub static ref HIER_ROOT_ADDR: Address = HIER_ROOT_INVARIANT.entity().unwrap();
pub static ref TYPE_HASH_ADDRESS: Address = pub static ref TYPE_HASH_ADDRESS: Address =
Address::Hash(crate::hash::UpMultihash(LargeMultihash::default())); Address::Hash(UpMultihash::from(LargeMultihash::default()));
pub static ref TYPE_UUID_ADDRESS: Address = Address::Uuid(uuid::Uuid::nil()); pub static ref TYPE_UUID_ADDRESS: Address = Address::Uuid(uuid::Uuid::nil());
pub static ref TYPE_ATTRIBUTE_ADDRESS: Address = Address::Attribute("".to_string()); pub static ref TYPE_ATTRIBUTE_ADDRESS: Address = Address::Attribute("".to_string());
pub static ref TYPE_URL_ADDRESS: Address = Address::Url(url::Url::parse("up:").unwrap()); pub static ref TYPE_URL_ADDRESS: Address = Address::Url(url::Url::parse("up:").unwrap());

View File

@ -7,17 +7,48 @@ use serde::{
ser, Deserialize, Deserializer, Serialize, Serializer, ser, Deserialize, Deserializer, Serialize, Serializer,
}; };
pub type LargeMultihash = multihash::MultihashGeneric<256>;
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "diesel", derive(diesel::FromSqlRow))]
pub struct UpMultihash(pub LargeMultihash);
/// multihash SHA2-256 code /// multihash SHA2-256 code
pub const SHA2_256: u64 = 0x12; pub const SHA2_256: u64 = 0x12;
/// multihash identity code /// multihash identity code
pub const IDENTITY: u64 = 0x00; pub const IDENTITY: u64 = 0x00;
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "diesel", derive(diesel::FromSqlRow))]
pub struct UpMultihash(LargeMultihash);
impl UpMultihash {
pub fn to_bytes(&self) -> Vec<u8> {
self.0.to_bytes()
}
pub fn from_bytes<T: AsRef<[u8]>>(input: T) -> Result<Self, UpEndError> {
Ok(UpMultihash(
LargeMultihash::from_bytes(input.as_ref())
.map_err(|e| UpEndError::HashDecodeError(e.to_string()))?,
))
}
pub fn from_sha256<T: AsRef<[u8]>>(input: T) -> Result<Self, UpEndError> {
Ok(UpMultihash(
LargeMultihash::wrap(SHA2_256, input.as_ref()).map_err(UpEndError::from_any)?,
))
}
}
pub(crate) type LargeMultihash = multihash::MultihashGeneric<256>;
impl From<LargeMultihash> for UpMultihash {
fn from(value: LargeMultihash) -> Self {
UpMultihash(value)
}
}
impl From<&UpMultihash> for LargeMultihash {
fn from(value: &UpMultihash) -> Self {
value.0
}
}
impl Serialize for UpMultihash { impl Serialize for UpMultihash {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error> fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where where

View File

@ -307,10 +307,7 @@ async fn main() -> Result<()> {
AddressType::File => hash_path(&input)?, AddressType::File => hash_path(&input)?,
AddressType::Sha256sum => { AddressType::Sha256sum => {
let digest = multibase::Base::Base16Lower.decode(input)?; let digest = multibase::Base::Base16Lower.decode(input)?;
Address::Hash(UpMultihash( Address::Hash(UpMultihash::from_sha256(&digest).unwrap())
upend_base::hash::LargeMultihash::wrap(upend_base::hash::SHA2_256, &digest)
.unwrap(),
))
} }
}; };

View File

@ -61,7 +61,7 @@ impl PreviewStore {
} else { } else {
let thumbpath = self.path.join(format!( let thumbpath = self.path.join(format!(
"{}{}", "{}{}",
b58_encode(hash.0.to_bytes()), b58_encode(hash.to_bytes()),
if options_concat.is_empty() { if options_concat.is_empty() {
String::from("") String::from("")
} else { } else {

View File

@ -1010,14 +1010,8 @@ mod tests {
>(None, vec![], get_state())) >(None, vec![], get_state()))
.await; .await;
let digest = UpMultihash( let digest = UpMultihash::from_sha256(&vec![1, 2, 3, 4, 5]).unwrap();
upend_base::hash::LargeMultihash::wrap( let digest_str = b58_encode(&digest.to_bytes());
upend_base::hash::IDENTITY,
&vec![1, 2, 3, 4, 5],
)
.unwrap(),
);
let digest_str = b58_encode(&digest.0.to_bytes());
let address = Address::Hash(digest); let address = Address::Hash(digest);
let req = actix_web::test::TestRequest::get() let req = actix_web::test::TestRequest::get()
.uri(&format!("/api/obj/{}", address.to_string())) .uri(&format!("/api/obj/{}", address.to_string()))

View File

@ -24,7 +24,7 @@ use tracing::{debug, error, info, trace, warn};
use upend_base::addressing::Address; use upend_base::addressing::Address;
use upend_base::constants::{ATTR_ADDED, ATTR_BY, ATTR_IN, ATTR_LABEL, ATTR_OF, TYPE_HASH_ADDRESS}; use upend_base::constants::{ATTR_ADDED, ATTR_BY, ATTR_IN, ATTR_LABEL, ATTR_OF, TYPE_HASH_ADDRESS};
use upend_base::entry::Entry; use upend_base::entry::Entry;
use upend_base::hash::{b58_encode, LargeMultihash, UpMultihash}; use upend_base::hash::{b58_encode, UpMultihash};
use walkdir::WalkDir; use walkdir::WalkDir;
mod db; mod db;
@ -393,7 +393,7 @@ impl FsStore {
.to_str() .to_str()
.ok_or(anyhow!("Path not UTF-8?!"))? .ok_or(anyhow!("Path not UTF-8?!"))?
.to_string(), .to_string(),
hash: hash.0.to_bytes(), hash: hash.to_bytes(),
added: NaiveDateTime::from_timestamp_opt(Utc::now().timestamp(), 0).unwrap(), added: NaiveDateTime::from_timestamp_opt(Utc::now().timestamp(), 0).unwrap(),
size, size,
mtime, mtime,
@ -494,7 +494,7 @@ impl FsStore {
debug!( debug!(
"Inserting {} ({})...", "Inserting {} ({})...",
&file.path, &file.path,
Address::Hash(UpMultihash(LargeMultihash::from_bytes(&file.hash)?)) Address::Hash(UpMultihash::from_bytes(&file.hash)?)
); );
let _lock = self.lock.write().unwrap(); let _lock = self.lock.write().unwrap();
@ -521,7 +521,7 @@ impl FsStore {
let matches = files let matches = files
.filter(valid.eq(true)) .filter(valid.eq(true))
.filter(hash.eq(&obj_hash.0.to_bytes())) .filter(hash.eq(&obj_hash.to_bytes()))
.load::<db::File>(&conn)?; .load::<db::File>(&conn)?;
let matches = matches let matches = matches