Skip to main content

rust_ipfs/repo/store/
default_impl.rs

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