ipfrs_storage/
traits.rs

1//! Storage traits
2
3use async_trait::async_trait;
4use ipfrs_core::{Block, Cid, Result};
5use std::sync::Arc;
6
7/// Trait for block storage backends
8#[async_trait]
9pub trait BlockStore: Send + Sync {
10    /// Store a single block
11    async fn put(&self, block: &Block) -> Result<()>;
12
13    /// Store multiple blocks atomically
14    async fn put_many(&self, blocks: &[Block]) -> Result<()> {
15        // Default implementation: sequential puts
16        for block in blocks {
17            self.put(block).await?;
18        }
19        Ok(())
20    }
21
22    /// Retrieve a block by CID
23    async fn get(&self, cid: &Cid) -> Result<Option<Block>>;
24
25    /// Retrieve multiple blocks
26    async fn get_many(&self, cids: &[Cid]) -> Result<Vec<Option<Block>>> {
27        // Default implementation: sequential gets
28        let mut results = Vec::with_capacity(cids.len());
29        for cid in cids {
30            results.push(self.get(cid).await?);
31        }
32        Ok(results)
33    }
34
35    /// Check if a block exists
36    async fn has(&self, cid: &Cid) -> Result<bool>;
37
38    /// Check if multiple blocks exist
39    async fn has_many(&self, cids: &[Cid]) -> Result<Vec<bool>> {
40        // Default implementation: sequential checks
41        let mut results = Vec::with_capacity(cids.len());
42        for cid in cids {
43            results.push(self.has(cid).await?);
44        }
45        Ok(results)
46    }
47
48    /// Delete a block
49    async fn delete(&self, cid: &Cid) -> Result<()>;
50
51    /// Delete multiple blocks
52    async fn delete_many(&self, cids: &[Cid]) -> Result<()> {
53        // Default implementation: sequential deletes
54        for cid in cids {
55            self.delete(cid).await?;
56        }
57        Ok(())
58    }
59
60    /// List all CIDs in the store
61    fn list_cids(&self) -> Result<Vec<Cid>>;
62
63    /// Get number of blocks
64    fn len(&self) -> usize;
65
66    /// Check if store is empty
67    fn is_empty(&self) -> bool {
68        self.len() == 0
69    }
70
71    /// Flush any pending writes
72    async fn flush(&self) -> Result<()> {
73        // Default: no-op
74        Ok(())
75    }
76
77    /// Close the store and release resources
78    async fn close(&self) -> Result<()> {
79        // Default: flush then no-op
80        self.flush().await
81    }
82}
83
84/// Blanket implementation for `Arc<S>` where `S: BlockStore`
85/// This allows Arc-wrapped stores to be used transparently
86#[async_trait]
87impl<S: BlockStore> BlockStore for Arc<S> {
88    async fn put(&self, block: &Block) -> Result<()> {
89        (**self).put(block).await
90    }
91
92    async fn put_many(&self, blocks: &[Block]) -> Result<()> {
93        (**self).put_many(blocks).await
94    }
95
96    async fn get(&self, cid: &Cid) -> Result<Option<Block>> {
97        (**self).get(cid).await
98    }
99
100    async fn get_many(&self, cids: &[Cid]) -> Result<Vec<Option<Block>>> {
101        (**self).get_many(cids).await
102    }
103
104    async fn has(&self, cid: &Cid) -> Result<bool> {
105        (**self).has(cid).await
106    }
107
108    async fn has_many(&self, cids: &[Cid]) -> Result<Vec<bool>> {
109        (**self).has_many(cids).await
110    }
111
112    async fn delete(&self, cid: &Cid) -> Result<()> {
113        (**self).delete(cid).await
114    }
115
116    async fn delete_many(&self, cids: &[Cid]) -> Result<()> {
117        (**self).delete_many(cids).await
118    }
119
120    fn list_cids(&self) -> Result<Vec<Cid>> {
121        (**self).list_cids()
122    }
123
124    fn len(&self) -> usize {
125        (**self).len()
126    }
127
128    fn is_empty(&self) -> bool {
129        (**self).is_empty()
130    }
131
132    async fn flush(&self) -> Result<()> {
133        (**self).flush().await
134    }
135
136    async fn close(&self) -> Result<()> {
137        (**self).close().await
138    }
139}