upend/src/hash.rs

82 lines
1.9 KiB
Rust

use actix::prelude::*;
use anyhow::{anyhow, Result};
use filebuffer::FileBuffer;
use std::path::{Path, PathBuf};
use tiny_keccak::{Hasher, KangarooTwelve};
#[derive(Debug, Clone, PartialEq)]
pub struct Hash(pub Vec<u8>);
// impl Hash {
// pub fn encode(&self) -> String {
// encode(self.0.clone()).into_string()
// }
//
// pub fn decode<T: AsRef<str>>(string: T) -> Result<Hash> {
// Ok(Hash(decode(string.as_ref())?))
// }
// }
// impl std::fmt::Display for Hash {
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// write!(f, "{}", self.encode())
// }
// }
pub trait Hashable {
fn hash(&self) -> Result<Hash>;
}
pub struct HasherWorker;
impl Actor for HasherWorker {
type Context = SyncContext<Self>;
}
#[derive(Message)]
#[rtype(result = "Result<Hash>")]
pub struct ComputeHash {
pub path: PathBuf,
}
impl Handler<ComputeHash> for HasherWorker {
type Result = Result<Hash>;
fn handle(&mut self, msg: ComputeHash, _: &mut Self::Context) -> Self::Result {
msg.path.hash()
}
}
impl Hashable for Path {
fn hash(self: &Path) -> Result<Hash> {
let fbuffer = FileBuffer::open(self)?;
Ok(hash(&fbuffer))
}
}
pub fn hash<T: AsRef<[u8]>>(input: T) -> Hash {
let mut k12 = KangarooTwelve::new(b"");
k12.update(input.as_ref());
let mut result = [0u8; 256 / 8];
k12.finalize(&mut result);
Hash(Vec::from(result))
}
pub fn encode<T: AsRef<[u8]>>(vec: T) -> String {
// multibase base58
format!("z{}", bs58::encode(vec).into_string())
}
pub fn decode<T: AsRef<str>>(string: T) -> Result<Vec<u8>> {
let string = string.as_ref();
let (base, data) = string.split_at(1);
// multibase base58
if base != "z" {
Err(anyhow!("data not base58 encoded, bailing"))
} else {
Ok(bs58::decode(data).into_vec()?)
}
}