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