Skip to main content

object_rainbow_store_opendal/
lib.rs

1use object_rainbow::{Hash, ObjectHashes, OptionalHash, ParseSliceRefless, ToOutput};
2use object_rainbow_store::{RainbowStore, RainbowStoreMut};
3use opendal::{ErrorKind, Operator};
4
5#[derive(Debug, Clone)]
6pub struct OpendalStore {
7    operator: Operator,
8}
9
10impl OpendalStore {
11    pub fn from_operator(operator: Operator) -> Self {
12        Self { operator }
13    }
14}
15
16impl RainbowStore for OpendalStore {
17    async fn save_data(&self, hashes: ObjectHashes, data: &[u8]) -> object_rainbow::Result<()> {
18        self.operator
19            .write(&hex::encode(hashes.data_hash()), data.to_vec())
20            .await
21            .map_err(object_rainbow::Error::io)?;
22        Ok(())
23    }
24
25    async fn contains(&self, hash: Hash) -> object_rainbow::Result<bool> {
26        self.operator
27            .exists(&hex::encode(hash))
28            .await
29            .map_err(object_rainbow::Error::io)
30    }
31
32    async fn fetch(
33        &self,
34        hash: Hash,
35    ) -> object_rainbow::Result<impl 'static + Send + Sync + AsRef<[u8]>> {
36        self.operator
37            .read(&hex::encode(hash))
38            .await
39            .map_err(object_rainbow::Error::io)
40            .map(|b| b.to_bytes())
41    }
42}
43
44impl RainbowStoreMut for OpendalStore {
45    async fn update_ref(
46        &self,
47        key: &str,
48        _old: Option<OptionalHash>,
49        hash: Hash,
50    ) -> object_rainbow::Result<()> {
51        self.operator
52            .write(key, hash.to_vec())
53            .await
54            .map_err(object_rainbow::Error::io)?;
55        Ok(())
56    }
57
58    async fn fetch_ref(&self, key: &str) -> object_rainbow::Result<OptionalHash> {
59        match self.operator.read(key).await {
60            Ok(value) => OptionalHash::parse_slice_refless(&value.to_vec()),
61            Err(e) if e.kind() == ErrorKind::NotFound => Ok(Default::default()),
62            Err(e) => Err(object_rainbow::Error::io(e)),
63        }
64    }
65
66    async fn ref_exists(&self, key: &str) -> object_rainbow::Result<bool> {
67        self.operator
68            .exists(key)
69            .await
70            .map_err(object_rainbow::Error::io)
71    }
72}