fuchsia_merkle/
lib.rs

1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! `fuchsia_merkle` contains types and methods for building and working with merkle trees.
6
7#![deny(missing_docs)]
8
9use futures::{AsyncRead, AsyncReadExt as _};
10use std::io::{self, Read};
11
12pub use fuchsia_hash::{Hash, HASH_SIZE};
13
14/// The size of a single block of data (or hashes), in bytes.
15pub 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
29/// Compute a merkle tree from a `&[u8]`.
30pub fn from_slice(slice: &[u8]) -> MerkleTree {
31    let mut builder = MerkleTreeBuilder::new();
32    builder.write(slice);
33    builder.finish()
34}
35
36/// Compute a merkle tree from a `std::io::Read`.
37pub fn from_read<R>(reader: &mut R) -> Result<MerkleTree, io::Error>
38where
39    R: Read,
40{
41    MerkleTree::from_reader(reader)
42}
43
44/// Compute a merkle tree from a `futures::io::AsyncRead`.
45pub 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}