diff --git a/examples/custom-protocol.rs b/examples/custom-protocol.rs index c021b7f0..82e8c656 100644 --- a/examples/custom-protocol.rs +++ b/examples/custom-protocol.rs @@ -100,7 +100,7 @@ async fn listen(text: Vec) -> Result<()> { proto.insert_and_index(text).await?; } // Build the iroh-blobs protocol handler, which is used to download blobs. - let blobs = BlobsProtocol::new(&store, endpoint.clone(), None); + let blobs = BlobsProtocol::builder(&store).build(&endpoint); // create a router that handles both our custom protocol and the iroh-blobs protocol. let node = Router::builder(endpoint) diff --git a/examples/mdns-discovery.rs b/examples/mdns-discovery.rs index b42f88f4..1b4b35dc 100644 --- a/examples/mdns-discovery.rs +++ b/examples/mdns-discovery.rs @@ -68,7 +68,7 @@ async fn accept(path: &Path) -> Result<()> { .await?; let builder = Router::builder(endpoint.clone()); let store = MemStore::new(); - let blobs = BlobsProtocol::new(&store, endpoint.clone(), None); + let blobs = BlobsProtocol::builder(&store).build(&endpoint); let builder = builder.accept(iroh_blobs::ALPN, blobs.clone()); let node = builder.spawn(); diff --git a/examples/random_store.rs b/examples/random_store.rs index 771fb411..6a7d043e 100644 --- a/examples/random_store.rs +++ b/examples/random_store.rs @@ -237,7 +237,9 @@ async fn provide(args: ProvideArgs) -> anyhow::Result<()> { .bind() .await?; let (dump_task, events_tx) = dump_provider_events(args.allow_push); - let blobs = iroh_blobs::BlobsProtocol::new(&store, endpoint.clone(), Some(events_tx)); + let blobs = iroh_blobs::BlobsProtocol::builder(&store) + .events(events_tx) + .build(&endpoint); let router = iroh::protocol::Router::builder(endpoint.clone()) .accept(iroh_blobs::ALPN, blobs) .spawn(); diff --git a/src/net_protocol.rs b/src/net_protocol.rs index 4ca3778a..405b7cae 100644 --- a/src/net_protocol.rs +++ b/src/net_protocol.rs @@ -36,7 +36,7 @@ //! # } //! ``` -use std::{fmt::Debug, future::Future, ops::Deref, sync::Arc}; +use std::{fmt::Debug, future::Future, ops::Deref, path::Path, sync::Arc}; use iroh::{ endpoint::Connection, @@ -49,6 +49,7 @@ use tracing::error; use crate::{ api::Store, provider::{Event, EventSender}, + store::{fs::FsStore, mem::MemStore}, ticket::BlobTicket, HashAndFormat, }; @@ -66,6 +67,32 @@ pub struct BlobsProtocol { pub(crate) inner: Arc, } +/// A builder for the blobs protocol handler. +pub struct BlobsProtocolBuilder { + pub store: Store, + pub events: Option>, +} + +impl BlobsProtocolBuilder { + fn new(store: Store) -> Self { + Self { + store, + events: None, + } + } + + /// Set provider events. + pub fn events(mut self, events: mpsc::Sender) -> Self { + self.events = Some(events); + self + } + + /// Build the blobs protocol handler. + pub fn build(self, endpoint: &Endpoint) -> BlobsProtocol { + BlobsProtocol::new(&self.store, endpoint.clone(), self.events) + } +} + impl Deref for BlobsProtocol { type Target = Store; @@ -85,6 +112,22 @@ impl BlobsProtocol { } } + /// Create a new Blobs protocol handler builder, given a store. + pub fn builder(store: &Store) -> BlobsProtocolBuilder { + BlobsProtocolBuilder::new(store.clone()) + } + + /// Create a new memory-backed Blobs protocol handler. + pub fn memory() -> BlobsProtocolBuilder { + Self::builder(&MemStore::new()) + } + + /// Load a persistent Blobs protocol handler from a path. + pub async fn persistent(path: impl AsRef) -> anyhow::Result { + let store = FsStore::load(path).await?; + Ok(Self::builder(&store)) + } + pub fn store(&self) -> &Store { &self.inner.store }