#![deny(missing_docs)]
use futures::{AsyncRead, AsyncReadExt as _};
use std::io::{self, Read};
pub use fuchsia_hash::{Hash, HASH_SIZE};
pub const BLOCK_SIZE: usize = 8192;
mod util;
pub use crate::util::{crypto_library_init, hash_block};
mod tree;
pub use crate::tree::MerkleTree;
mod builder;
pub use crate::builder::MerkleTreeBuilder;
mod writer;
pub use crate::writer::MerkleTreeWriter;
pub fn from_slice(slice: &[u8]) -> MerkleTree {
let mut builder = MerkleTreeBuilder::new();
builder.write(slice);
builder.finish()
}
pub fn from_read<R>(reader: &mut R) -> Result<MerkleTree, io::Error>
where
R: Read,
{
MerkleTree::from_reader(reader)
}
pub async fn from_async_read<R>(reader: &mut R) -> Result<MerkleTree, io::Error>
where
R: AsyncRead + Unpin,
{
let mut buf = [0; BLOCK_SIZE];
let mut builder = MerkleTreeBuilder::new();
loop {
let len = reader.read(&mut buf).await?;
if len == 0 {
break;
}
builder.write(&buf[0..len]);
}
Ok(builder.finish())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_from_slice() {
let file = b"hello world";
let mut builder = MerkleTreeBuilder::new();
builder.write(&file[..]);
let expected = builder.finish();
let actual = from_slice(&file[..]);
assert_eq!(expected, actual);
}
#[test]
fn test_from_read() {
let file = b"hello world";
let mut builder = MerkleTreeBuilder::new();
builder.write(&file[..]);
let expected = builder.finish();
let actual = from_read(&mut &file[..]).unwrap();
assert_eq!(expected, actual);
}
#[test]
fn test_from_async_read() {
futures::executor::block_on(async {
let file = b"hello world";
let mut builder = MerkleTreeBuilder::new();
builder.write(&file[..]);
let expected = builder.finish();
let actual = from_async_read(&mut &file[..]).await.unwrap();
assert_eq!(expected, actual);
})
}
}