Skip to content

Commit

Permalink
refactor: Conditionally compile Send bounds instead of SendWrapper (
Browse files Browse the repository at this point in the history
  • Loading branch information
matheus23 authored Apr 3, 2024
1 parent 102bafd commit d6ab1f5
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 47 deletions.
10 changes: 0 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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"]
Expand Down
33 changes: 33 additions & 0 deletions src/cond_send.rs
Original file line number Diff line number Diff line change
@@ -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<S> CondSend for S where S: Send {}

#[cfg(target_arch = "wasm32")]
impl<S> 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<S> CondSync for S where S: Send + Sync {}

#[cfg(target_arch = "wasm32")]
impl<S> CondSync for S {}
32 changes: 7 additions & 25 deletions src/indexed_db_blockstore.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -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<Rexie>,
db: Rexie,
}

impl IndexedDbBlockstore {
Expand All @@ -30,18 +29,18 @@ impl IndexedDbBlockstore {
/// # }
/// ```
pub async fn new(name: &str) -> Result<Self> {
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<const S: usize>(&self, cid: &CidGeneric<S>) -> Result<Option<Vec<u8>>> {
let cid = Uint8Array::from(cid.to_bytes().as_ref());

Expand All @@ -67,7 +66,7 @@ impl IndexedDbBlockstore {
}
}

async fn put<const S: usize>(&self, cid: &CidGeneric<S>, data: &[u8]) -> Result<()> {
async fn put_keyed<const S: usize>(&self, cid: &CidGeneric<S>, data: &[u8]) -> Result<()> {
let cid = Uint8Array::from(cid.to_bytes().as_ref());
let data = Uint8Array::from(data);

Expand All @@ -94,23 +93,6 @@ impl IndexedDbBlockstore {
}
}

impl Blockstore for IndexedDbBlockstore {
async fn get<const S: usize>(&self, cid: &CidGeneric<S>) -> Result<Option<Vec<u8>>> {
let fut = SendWrapper::new(self.get(cid));
fut.await
}

async fn put_keyed<const S: usize>(&self, cid: &CidGeneric<S>, data: &[u8]) -> Result<()> {
let fut = SendWrapper::new(self.put(cid, data));
fut.await
}

async fn has<const S: usize>(&self, cid: &CidGeneric<S>) -> Result<bool> {
let fut = SendWrapper::new(self.has(cid));
fut.await
}
}

impl From<rexie::Error> for BlockstoreError {
fn from(value: rexie::Error) -> Self {
BlockstoreError::BackingStoreError(value.to_string())
Expand Down Expand Up @@ -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();
Expand Down
25 changes: 15 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
use std::future::Future;

use cid::CidGeneric;
use cond_send::{CondSend, CondSync};
use multihash::Multihash;
use thiserror::Error;

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;
Expand Down Expand Up @@ -62,12 +64,12 @@ type Result<T, E = BlockstoreError> = std::result::Result<T, E>;
/// will fail with [`CidTooLong`].
///
/// [`CidTooLong`]: BlockstoreError::CidTooLong
pub trait Blockstore: Send + Sync {
pub trait Blockstore: CondSync {
/// Gets the block from the blockstore
fn get<const S: usize>(
&self,
cid: &CidGeneric<S>,
) -> impl Future<Output = Result<Option<Vec<u8>>>> + Send;
) -> impl Future<Output = Result<Option<Vec<u8>>>> + CondSend;

/// Inserts the data with pre-computed CID.
/// Use [`put`], if you want CID to be computed.
Expand All @@ -77,18 +79,18 @@ pub trait Blockstore: Send + Sync {
&self,
cid: &CidGeneric<S>,
data: &[u8],
) -> impl Future<Output = Result<()>> + Send;
) -> impl Future<Output = Result<()>> + CondSend;

/// Checks whether blockstore has block for provided CID
fn has<const S: usize>(
&self,
cid: &CidGeneric<S>,
) -> impl Future<Output = Result<bool>> + Send {
) -> impl Future<Output = Result<bool>> + CondSend {
async { Ok(self.get(cid).await?.is_some()) }
}

/// Inserts the data into the blockstore, computing CID using [`Block`] trait.
fn put<const S: usize, B>(&self, block: B) -> impl Future<Output = Result<()>> + Send
fn put<const S: usize, B>(&self, block: B) -> impl Future<Output = Result<()>> + CondSend
where
B: Block<S>,
{
Expand All @@ -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<const S: usize, B, I>(&self, blocks: I) -> impl Future<Output = Result<()>> + Send
fn put_many<const S: usize, B, I>(
&self,
blocks: I,
) -> impl Future<Output = Result<()>> + CondSend
where
B: Block<S>,
I: IntoIterator<Item = B> + Send,
I: IntoIterator<Item = B> + CondSend,
<I as IntoIterator>::IntoIter: Send,
{
async move {
Expand All @@ -121,10 +126,10 @@ pub trait Blockstore: Send + Sync {
fn put_many_keyed<const S: usize, D, I>(
&self,
blocks: I,
) -> impl Future<Output = Result<()>> + Send
) -> impl Future<Output = Result<()>> + CondSend
where
D: AsRef<[u8]> + Send + Sync,
I: IntoIterator<Item = (CidGeneric<S>, D)> + Send,
D: AsRef<[u8]> + CondSync,
I: IntoIterator<Item = (CidGeneric<S>, D)> + CondSend,
<I as IntoIterator>::IntoIter: Send,
{
async move {
Expand Down

0 comments on commit d6ab1f5

Please sign in to comment.