Skip to main content

rust_ipfs/repo/store/
default_impl.rs

1pub mod keystore;
2
3#[cfg(not(target_arch = "wasm32"))]
4use crate::repo::store::blockstore::flatfs::FsBlockStore;
5#[cfg(target_arch = "wasm32")]
6use crate::repo::store::blockstore::idb::IdbBlockStore;
7use crate::repo::store::blockstore::memory::MemBlockStore;
8#[cfg(not(target_arch = "wasm32"))]
9use crate::repo::store::datastore::flatfs::FsDataStore;
10#[cfg(target_arch = "wasm32")]
11use crate::repo::store::datastore::idb::IdbDataStore;
12use crate::repo::store::datastore::memory::MemDataStore;
13use crate::repo::{
14    BlockPut, BlockStore, DataStore, Lock, LockError, PinStore, References, RepoTypes, lock,
15};
16use crate::{Block, PinKind, PinMode};
17
18#[cfg(target_arch = "wasm32")]
19use std::sync::Arc;
20
21use either::Either;
22use futures::stream::BoxStream;
23use ipld_core::cid::Cid;
24
25use crate::error::Error;
26
27#[derive(Debug)]
28#[cfg(not(target_arch = "wasm32"))]
29pub struct DefaultStorage {
30    blockstore: Either<MemBlockStore, FsBlockStore>,
31    datastore: Either<MemDataStore, FsDataStore>,
32    lockfile: Either<lock::MemLock, lock::FsLock>,
33}
34
35#[derive(Debug)]
36#[cfg(target_arch = "wasm32")]
37pub struct DefaultStorage {
38    blockstore: Either<MemBlockStore, Arc<IdbBlockStore>>,
39    datastore: Either<MemDataStore, Arc<IdbDataStore>>,
40    lockfile: Either<lock::MemLock, lock::MemLock>,
41}
42
43impl Default for DefaultStorage {
44    fn default() -> Self {
45        Self {
46            blockstore: Either::Left(MemBlockStore::new(Default::default())),
47            datastore: Either::Left(MemDataStore::new(Default::default())),
48            lockfile: Either::Left(lock::MemLock),
49        }
50    }
51}
52
53#[cfg(not(target_arch = "wasm32"))]
54impl DefaultStorage {
55    /// Set path to trigger persistent storage
56    #[allow(dead_code)]
57    pub(crate) fn set_path(&mut self, path: impl AsRef<std::path::Path>) {
58        let path = path.as_ref().to_path_buf();
59        self.blockstore = Either::Right(FsBlockStore::new(path.clone()));
60        self.datastore = Either::Right(FsDataStore::new(path.clone()));
61        self.lockfile = Either::Right(lock::FsLock::new(path.clone()));
62    }
63
64    pub(crate) fn set_blockstore_path(&mut self, path: impl AsRef<std::path::Path>) {
65        let path = path.as_ref().to_path_buf();
66        self.blockstore = Either::Right(FsBlockStore::new(path.clone()));
67    }
68
69    pub(crate) fn set_datastore_path(&mut self, path: impl AsRef<std::path::Path>) {
70        let path = path.as_ref().to_path_buf();
71        self.datastore = Either::Right(FsDataStore::new(path.clone()));
72    }
73
74    pub(crate) fn set_lockfile(&mut self, path: impl AsRef<std::path::Path>) {
75        let path = path.as_ref().to_path_buf();
76        self.lockfile = Either::Right(lock::FsLock::new(path.clone()));
77    }
78
79    #[allow(dead_code)]
80    pub(crate) fn remove_paths(&mut self) {
81        self.blockstore = Either::Left(MemBlockStore::new(Default::default()));
82        self.datastore = Either::Left(MemDataStore::new(Default::default()));
83        self.lockfile = Either::Left(lock::MemLock);
84    }
85}
86
87#[cfg(target_arch = "wasm32")]
88impl DefaultStorage {
89    /// Set path to trigger persistent storage
90    pub(crate) fn set_namespace(&mut self, namespace: impl Into<Option<String>>) {
91        let namespace = namespace.into();
92        self.blockstore = Either::Right(Arc::new(IdbBlockStore::new(namespace.clone())));
93        self.datastore = Either::Right(Arc::new(IdbDataStore::new(namespace.clone())));
94        self.lockfile = Either::Right(lock::MemLock);
95    }
96
97    #[allow(dead_code)]
98    pub(crate) fn remove_namespace(&mut self) {
99        self.blockstore = Either::Left(MemBlockStore::new(Default::default()));
100        self.datastore = Either::Left(MemDataStore::new(Default::default()));
101        self.lockfile = Either::Left(lock::MemLock);
102    }
103}
104
105impl Clone for DefaultStorage {
106    fn clone(&self) -> Self {
107        Self {
108            blockstore: self.blockstore.clone(),
109            datastore: self.datastore.clone(),
110            lockfile: self.lockfile.clone(),
111        }
112    }
113}
114
115impl RepoTypes for DefaultStorage {
116    type TBlockStore = DefaultStorage;
117    type TDataStore = DefaultStorage;
118    type TLock = DefaultStorage;
119}
120
121impl Unpin for DefaultStorage {}
122
123impl BlockStore for DefaultStorage {
124    async fn init(&self) -> Result<(), Error> {
125        self.blockstore.init().await
126    }
127
128    async fn contains(&self, cid: &Cid) -> Result<bool, Error> {
129        self.blockstore.contains(cid).await
130    }
131
132    async fn get(&self, cid: &Cid) -> Result<Option<Block>, Error> {
133        self.blockstore.get(cid).await
134    }
135
136    async fn size(&self, cid: &[Cid]) -> Result<Option<usize>, Error> {
137        self.blockstore.size(cid).await
138    }
139
140    async fn total_size(&self) -> Result<usize, Error> {
141        self.blockstore.total_size().await
142    }
143
144    async fn put(&self, block: &Block) -> Result<(Cid, BlockPut), Error> {
145        self.blockstore.put(block).await
146    }
147
148    async fn put_many(&self, blocks: &[Block]) -> Result<Vec<(Cid, BlockPut)>, Error> {
149        self.blockstore.put_many(blocks).await
150    }
151
152    async fn remove(&self, cid: &Cid) -> Result<(), Error> {
153        self.blockstore.remove(cid).await
154    }
155
156    async fn remove_many(&self, blocks: BoxStream<'static, Cid>) -> BoxStream<'static, Cid> {
157        self.blockstore.remove_many(blocks).await
158    }
159
160    async fn list(&self) -> BoxStream<'static, Cid> {
161        self.blockstore.list().await
162    }
163}
164
165impl DataStore for DefaultStorage {
166    async fn init(&self) -> Result<(), Error> {
167        self.datastore.init().await
168    }
169
170    async fn contains(&self, key: &[u8]) -> Result<bool, Error> {
171        self.datastore.contains(key).await
172    }
173
174    async fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
175        self.datastore.get(key).await
176    }
177
178    async fn put(&self, key: &[u8], value: &[u8]) -> Result<(), Error> {
179        self.datastore.put(key, value).await
180    }
181
182    async fn remove(&self, key: &[u8]) -> Result<(), Error> {
183        self.datastore.remove(key).await
184    }
185
186    async fn iter(&self) -> BoxStream<'static, (Vec<u8>, Vec<u8>)> {
187        self.datastore.iter().await
188    }
189}
190
191impl PinStore for DefaultStorage {
192    async fn is_pinned(&self, block: &Cid) -> Result<bool, Error> {
193        self.datastore.is_pinned(block).await
194    }
195
196    async fn insert_direct_pin(&self, target: &Cid) -> Result<(), Error> {
197        self.datastore.insert_direct_pin(target).await
198    }
199
200    async fn insert_recursive_pin(
201        &self,
202        target: &Cid,
203        referenced: References<'_>,
204    ) -> Result<(), Error> {
205        self.datastore
206            .insert_recursive_pin(target, referenced)
207            .await
208    }
209
210    async fn remove_direct_pin(&self, target: &Cid) -> Result<(), Error> {
211        self.datastore.remove_direct_pin(target).await
212    }
213
214    async fn remove_recursive_pin(
215        &self,
216        target: &Cid,
217        referenced: References<'_>,
218    ) -> Result<(), Error> {
219        self.datastore
220            .remove_recursive_pin(target, referenced)
221            .await
222    }
223
224    async fn list(
225        &self,
226        mode: Option<PinMode>,
227    ) -> BoxStream<'static, Result<(Cid, PinMode), Error>> {
228        self.datastore.list(mode).await
229    }
230
231    async fn query(
232        &self,
233        ids: Vec<Cid>,
234        requirement: Option<PinMode>,
235    ) -> Result<Vec<(Cid, PinKind<Cid>)>, Error> {
236        self.datastore.query(ids, requirement).await
237    }
238}
239
240impl Lock for DefaultStorage {
241    fn try_exclusive(&self) -> Result<(), LockError> {
242        self.lockfile.try_exclusive()
243    }
244}