Skip to main content

perfgate_server/storage/
artifacts.rs

1//! Artifact storage implementations using object_store.
2
3use super::ArtifactStore;
4use crate::error::StoreError;
5use async_trait::async_trait;
6use object_store::{ObjectStore, path::Path};
7use std::sync::Arc;
8
9/// Artifact storage using a generic ObjectStore (S3, GCS, Azure, Local).
10#[derive(Debug)]
11pub struct ObjectArtifactStore {
12    inner: Arc<dyn ObjectStore>,
13}
14
15impl ObjectArtifactStore {
16    /// Creates a new ObjectArtifactStore from an existing ObjectStore.
17    pub fn new(inner: Arc<dyn ObjectStore>) -> Self {
18        Self { inner }
19    }
20}
21
22#[async_trait]
23impl ArtifactStore for ObjectArtifactStore {
24    async fn put(&self, path: &str, data: Vec<u8>) -> Result<(), StoreError> {
25        let path = Path::from(path);
26        self.inner
27            .put(&path, data.into())
28            .await
29            .map_err(|e| StoreError::Other(format!("ObjectStore put failed: {}", e)))?;
30        Ok(())
31    }
32
33    async fn get(&self, path: &str) -> Result<Vec<u8>, StoreError> {
34        let path = Path::from(path);
35        let result = self
36            .inner
37            .get(&path)
38            .await
39            .map_err(|e| StoreError::Other(format!("ObjectStore get failed: {}", e)))?;
40
41        let bytes = result
42            .bytes()
43            .await
44            .map_err(|e| StoreError::Other(format!("ObjectStore bytes failed: {}", e)))?;
45
46        Ok(bytes.to_vec())
47    }
48
49    async fn delete(&self, path: &str) -> Result<(), StoreError> {
50        let path = Path::from(path);
51        self.inner
52            .delete(&path)
53            .await
54            .map_err(|e| StoreError::Other(format!("ObjectStore delete failed: {}", e)))?;
55        Ok(())
56    }
57}