From d6ab1f5b49294572f1003347162171307b8efc81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Kr=C3=BCger?= Date: Wed, 3 Apr 2024 14:49:31 +0200 Subject: [PATCH] refactor: Conditionally compile `Send` bounds instead of `SendWrapper` (#8) --- Cargo.lock | 10 ---------- Cargo.toml | 3 +-- src/cond_send.rs | 33 +++++++++++++++++++++++++++++++++ src/indexed_db_blockstore.rs | 32 +++++++------------------------- src/lib.rs | 25 +++++++++++++++---------- 5 files changed, 56 insertions(+), 47 deletions(-) create mode 100644 src/cond_send.rs diff --git a/Cargo.lock b/Cargo.lock index 9c0fc37..4b10949 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,7 +151,6 @@ dependencies = [ "multihash-codetable", "rexie", "rstest", - "send_wrapper", "sled", "tempfile", "thiserror", @@ -913,15 +912,6 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" -[[package]] -name = "send_wrapper" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" -dependencies = [ - "futures-core", -] - [[package]] name = "sha1" version = "0.10.6" diff --git a/Cargo.toml b/Cargo.toml index b2f2709..af02ed4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,6 @@ tokio = { version = "1.29.0", features = ["macros", "rt"], optional = true } [target.'cfg(target_arch = "wasm32")'.dependencies] js-sys = { version = "0.3.68", optional = true } rexie = { version = "0.5.0", optional = true } -send_wrapper = { version = "0.6.0", features = ["futures"], optional = true } wasm-bindgen = { version = "0.2.91", optional = true } [dev-dependencies] @@ -48,7 +47,7 @@ wasm-bindgen-test = "0.3.41" [features] lru = ["dep:lru"] sled = ["dep:sled", "dep:tokio"] -indexeddb = ["dep:js-sys", "dep:rexie", "dep:send_wrapper", "dep:wasm-bindgen"] +indexeddb = ["dep:js-sys", "dep:rexie", "dep:wasm-bindgen"] [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docs_rs"] diff --git a/src/cond_send.rs b/src/cond_send.rs new file mode 100644 index 0000000..df30005 --- /dev/null +++ b/src/cond_send.rs @@ -0,0 +1,33 @@ +//! Utilities for conditionally adding `Send` and `Sync` constraints. + +/// A conditionally compiled trait indirection for `Send` bounds. +/// This target makes it require `Send`. +#[cfg(not(target_arch = "wasm32"))] +pub trait CondSend: Send {} + +/// A conditionally compiled trait indirection for `Send` bounds. +/// This target makes it not require any marker traits. +#[cfg(target_arch = "wasm32")] +pub trait CondSend {} + +#[cfg(not(target_arch = "wasm32"))] +impl CondSend for S where S: Send {} + +#[cfg(target_arch = "wasm32")] +impl CondSend for S {} + +/// A conditionally compiled trait indirection for `Send + Sync` bounds. +/// This target makes it require `Send + Sync`. +#[cfg(not(target_arch = "wasm32"))] +pub trait CondSync: Send + Sync {} + +/// A conditionally compiled trait indirection for `Send + Sync` bounds. +/// This target makes it not require any marker traits. +#[cfg(target_arch = "wasm32")] +pub trait CondSync {} + +#[cfg(not(target_arch = "wasm32"))] +impl CondSync for S where S: Send + Sync {} + +#[cfg(target_arch = "wasm32")] +impl CondSync for S {} diff --git a/src/indexed_db_blockstore.rs b/src/indexed_db_blockstore.rs index df9fa19..6e27f5b 100644 --- a/src/indexed_db_blockstore.rs +++ b/src/indexed_db_blockstore.rs @@ -1,7 +1,6 @@ use cid::CidGeneric; use js_sys::Uint8Array; use rexie::{KeyRange, ObjectStore, Rexie, Store, TransactionMode}; -use send_wrapper::SendWrapper; use wasm_bindgen::{JsCast, JsValue}; use crate::{Blockstore, BlockstoreError, Result}; @@ -14,7 +13,7 @@ const BLOCK_STORE: &str = "BLOCKSTORE.BLOCKS"; /// A [`Blockstore`] implementation backed by an `IndexedDb` database. #[derive(Debug)] pub struct IndexedDbBlockstore { - db: SendWrapper, + db: Rexie, } impl IndexedDbBlockstore { @@ -30,18 +29,18 @@ impl IndexedDbBlockstore { /// # } /// ``` pub async fn new(name: &str) -> Result { - let rexie = Rexie::builder(name) + let db = Rexie::builder(name) .version(DB_VERSION) .add_object_store(ObjectStore::new(BLOCK_STORE).auto_increment(false)) .build() .await .map_err(|e| BlockstoreError::BackingStoreError(e.to_string()))?; - Ok(Self { - db: SendWrapper::new(rexie), - }) + Ok(Self { db }) } +} +impl Blockstore for IndexedDbBlockstore { async fn get(&self, cid: &CidGeneric) -> Result>> { let cid = Uint8Array::from(cid.to_bytes().as_ref()); @@ -67,7 +66,7 @@ impl IndexedDbBlockstore { } } - async fn put(&self, cid: &CidGeneric, data: &[u8]) -> Result<()> { + async fn put_keyed(&self, cid: &CidGeneric, data: &[u8]) -> Result<()> { let cid = Uint8Array::from(cid.to_bytes().as_ref()); let data = Uint8Array::from(data); @@ -94,23 +93,6 @@ impl IndexedDbBlockstore { } } -impl Blockstore for IndexedDbBlockstore { - async fn get(&self, cid: &CidGeneric) -> Result>> { - let fut = SendWrapper::new(self.get(cid)); - fut.await - } - - async fn put_keyed(&self, cid: &CidGeneric, data: &[u8]) -> Result<()> { - let fut = SendWrapper::new(self.put(cid, data)); - fut.await - } - - async fn has(&self, cid: &CidGeneric) -> Result { - let fut = SendWrapper::new(self.has(cid)); - fut.await - } -} - impl From for BlockstoreError { fn from(value: rexie::Error) -> Self { BlockstoreError::BackingStoreError(value.to_string()) @@ -144,7 +126,7 @@ mod tests { store.put_keyed(&cid, data).await.unwrap(); - store.db.take().close(); + store.db.close(); let store = IndexedDbBlockstore::new(store_name).await.unwrap(); let received = store.get(&cid).await.unwrap(); diff --git a/src/lib.rs b/src/lib.rs index 2825032..2c85f5a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ use std::future::Future; use cid::CidGeneric; +use cond_send::{CondSend, CondSync}; use multihash::Multihash; use thiserror::Error; @@ -11,6 +12,7 @@ use crate::block::{Block, CidError}; /// Utilities related to computing CID for the inserted data pub mod block; +pub mod cond_send; mod in_memory_blockstore; #[cfg(all(target_arch = "wasm32", feature = "indexeddb"))] mod indexed_db_blockstore; @@ -62,12 +64,12 @@ type Result = std::result::Result; /// will fail with [`CidTooLong`]. /// /// [`CidTooLong`]: BlockstoreError::CidTooLong -pub trait Blockstore: Send + Sync { +pub trait Blockstore: CondSync { /// Gets the block from the blockstore fn get( &self, cid: &CidGeneric, - ) -> impl Future>>> + Send; + ) -> impl Future>>> + CondSend; /// Inserts the data with pre-computed CID. /// Use [`put`], if you want CID to be computed. @@ -77,18 +79,18 @@ pub trait Blockstore: Send + Sync { &self, cid: &CidGeneric, data: &[u8], - ) -> impl Future> + Send; + ) -> impl Future> + CondSend; /// Checks whether blockstore has block for provided CID fn has( &self, cid: &CidGeneric, - ) -> impl Future> + Send { + ) -> impl Future> + CondSend { async { Ok(self.get(cid).await?.is_some()) } } /// Inserts the data into the blockstore, computing CID using [`Block`] trait. - fn put(&self, block: B) -> impl Future> + Send + fn put(&self, block: B) -> impl Future> + CondSend where B: Block, { @@ -101,10 +103,13 @@ pub trait Blockstore: Send + Sync { /// Inserts multiple blocks into the blockstore computing their CID /// If CID computation, or insert itself fails, error is returned and subsequent items are also /// skipped. - fn put_many(&self, blocks: I) -> impl Future> + Send + fn put_many( + &self, + blocks: I, + ) -> impl Future> + CondSend where B: Block, - I: IntoIterator + Send, + I: IntoIterator + CondSend, ::IntoIter: Send, { async move { @@ -121,10 +126,10 @@ pub trait Blockstore: Send + Sync { fn put_many_keyed( &self, blocks: I, - ) -> impl Future> + Send + ) -> impl Future> + CondSend where - D: AsRef<[u8]> + Send + Sync, - I: IntoIterator, D)> + Send, + D: AsRef<[u8]> + CondSync, + I: IntoIterator, D)> + CondSend, ::IntoIter: Send, { async move {