1#![deny(missing_docs)]
8
9use futures::{AsyncRead, AsyncReadExt as _};
10use std::io::{self, Read};
11
12pub use fuchsia_hash::{Hash, HASH_SIZE};
13
14pub const BLOCK_SIZE: usize = 8192;
16
17mod util;
18pub use crate::util::{crypto_library_init, hash_block};
19
20mod tree;
21pub use crate::tree::MerkleTree;
22
23mod builder;
24pub use crate::builder::MerkleTreeBuilder;
25
26mod writer;
27pub use crate::writer::MerkleTreeWriter;
28
29pub fn from_slice(slice: &[u8]) -> MerkleTree {
31 let mut builder = MerkleTreeBuilder::new();
32 builder.write(slice);
33 builder.finish()
34}
35
36pub fn from_read<R>(reader: &mut R) -> Result<MerkleTree, io::Error>
38where
39 R: Read,
40{
41 MerkleTree::from_reader(reader)
42}
43
44pub async fn from_async_read<R>(reader: &mut R) -> Result<MerkleTree, io::Error>
46where
47 R: AsyncRead + Unpin,
48{
49 let mut buf = [0; BLOCK_SIZE];
50 let mut builder = MerkleTreeBuilder::new();
51
52 loop {
53 let len = reader.read(&mut buf).await?;
54 if len == 0 {
55 break;
56 }
57 builder.write(&buf[0..len]);
58 }
59
60 Ok(builder.finish())
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[test]
68 fn test_from_slice() {
69 let file = b"hello world";
70 let mut builder = MerkleTreeBuilder::new();
71 builder.write(&file[..]);
72 let expected = builder.finish();
73
74 let actual = from_slice(&file[..]);
75 assert_eq!(expected, actual);
76 }
77
78 #[test]
79 fn test_from_read() {
80 let file = b"hello world";
81 let mut builder = MerkleTreeBuilder::new();
82 builder.write(&file[..]);
83 let expected = builder.finish();
84
85 let actual = from_read(&mut &file[..]).unwrap();
86 assert_eq!(expected, actual);
87 }
88
89 #[test]
90 fn test_from_async_read() {
91 futures::executor::block_on(async {
92 let file = b"hello world";
93 let mut builder = MerkleTreeBuilder::new();
94 builder.write(&file[..]);
95 let expected = builder.finish();
96
97 let actual = from_async_read(&mut &file[..]).await.unwrap();
98 assert_eq!(expected, actual);
99 })
100 }
101}