1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// Copyright 2024 Entanglement Contributors
// SPDX-License-Identifier: Apache-2.0, MIT
//! # Entanglement Storage Library
//!
//! The Entanglement Storage Library provides a unified interface for interacting with various storage backends.
//! It defines traits and implementations for uploading, downloading, and managing data in chunks. The library
//! supports both in-memory and persistent storage solutions, making it suitable for a wide range of applications.
//!
//! ## Modules
//!
//! - [`iroh`](iroh): Contains the implementation for the Iroh storage backend.
//! - [`storage`](storage): Defines the core traits and types for storage operations.
//! - [`mock`](mock): Provides a mock implementation of the storage traits for testing purposes.
//!
//! ## Traits
//!
//! - [`Storage`](storage::Storage): Represents a storage backend capable of uploading, downloading, and streaming data in chunks.
//! - [`ChunkId`](storage::ChunkId): A trait used to identify chunks.
//! - [`ChunkIdMapper`](storage::ChunkIdMapper): A trait for mapping chunk indices to chunk ids and vice versa.
//!
//! ## Error Handling
//!
//! The library uses the [`Error`](storage::Error) enum to represent various errors that can occur during storage operations.
//!
//! ## Usage
//!
//! To use the library, you need to implement the [`Storage`](storage::Storage) trait for your storage backend. The library provides
//! a default implementation for in-memory storage through the [`FakeStorage`](mock::FakeStorage) struct, which can be used for testing.
//!
//! ### Example
//!
//! ```rust
//! pub mod storage;
//! pub mod iroh;
//!
//! use crate::storage::Storage;
//! use crate::iroh::IrohStorage;
//! use bytes::Bytes;
//! use futures::StreamExt;
//!
//! #[tokio::main]
//! async fn main() -> anyhow::Result<()> {
//! let storage = IrohStorage::new_in_memory().await?;
//! let data = b"Hello, world!".to_vec();
//! let upload_result = storage.upload_bytes(data.clone()).await?;
//!
//! // Download the data as a single blob
//! let mut stream = storage.download_bytes(&upload_result.hash).await?;
//! let mut downloaded = Vec::with_capacity(stream.size_hint().0);
//! while let Some(chunk) = stream.next().await {
//! downloaded.extend_from_slice(&chunk?);
//! }
//! assert_eq!(data, downloaded);
//!
//! // Iterate through chunks
//! let mut chunk_stream = storage.iter_chunks(&upload_result.hash).await?;
//! while let Some((chunk_id, chunk_result)) = chunk_stream.next().await {
//! let chunk = chunk_result?;
//! println!("Got chunk {}: {:?} bytes", chunk_id, chunk.len());
//! }
//!
//! Ok(())
//! }
//! ```
pub use *;