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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use std::io::Cursor;
use anyhow::Result;
use async_trait::async_trait;
use cid::Cid;
use libipld_cbor::DagCborCodec;
use libipld_core::{
codec::{Codec, Decode},
ipld::Ipld,
serde::{from_ipld, to_ipld},
};
use serde::{de::DeserializeOwned, Serialize};
use crate::{
block::BlockStore,
key_value::{KeyValueStore, KeyValueStoreSend},
};
#[cfg(not(target_arch = "wasm32"))]
pub trait StoreConditionalSendSync: Send + Sync {}
#[cfg(not(target_arch = "wasm32"))]
impl<S> StoreConditionalSendSync for S where S: Send + Sync {}
#[cfg(target_arch = "wasm32")]
pub trait StoreConditionalSendSync {}
#[cfg(target_arch = "wasm32")]
impl<S> StoreConditionalSendSync for S {}
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
pub trait Store: Clone + StoreConditionalSendSync {
async fn read(&self, key: &[u8]) -> Result<Option<Vec<u8>>>;
async fn write(&mut self, key: &[u8], bytes: &[u8]) -> Result<Option<Vec<u8>>>;
async fn remove(&mut self, key: &[u8]) -> Result<Option<Vec<u8>>>;
async fn flush(&self) -> Result<()> {
Ok(())
}
}
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
impl<S> BlockStore for S
where
S: Store,
{
async fn put_block(&mut self, cid: &Cid, block: &[u8]) -> Result<()> {
self.write(&cid.to_bytes(), block).await?;
Ok(())
}
async fn get_block(&self, cid: &Cid) -> Result<Option<Vec<u8>>> {
self.read(&cid.to_bytes()).await
}
async fn flush(&self) -> Result<()> {
Store::flush(self).await
}
}
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
impl<S> KeyValueStore for S
where
S: Store,
{
async fn set_key<K, V>(&mut self, key: K, value: V) -> Result<()>
where
K: AsRef<[u8]> + KeyValueStoreSend,
V: Serialize + KeyValueStoreSend,
{
let ipld = to_ipld(value)?;
let codec = DagCborCodec;
let cbor = codec.encode(&ipld)?;
let key_bytes = K::as_ref(&key);
self.write(key_bytes, &cbor).await?;
Ok(())
}
async fn unset_key<K>(&mut self, key: K) -> Result<()>
where
K: AsRef<[u8]> + KeyValueStoreSend,
{
let key_bytes = K::as_ref(&key);
self.remove(key_bytes).await?;
Ok(())
}
async fn get_key<K, V>(&self, key: K) -> Result<Option<V>>
where
K: AsRef<[u8]> + KeyValueStoreSend,
V: DeserializeOwned + KeyValueStoreSend,
{
let key_bytes = K::as_ref(&key);
Ok(match self.read(key_bytes).await? {
Some(bytes) => Some(from_ipld(Ipld::decode(
DagCborCodec,
&mut Cursor::new(bytes),
)?)?),
None => None,
})
}
async fn flush(&self) -> Result<()> {
Store::flush(self).await
}
}