1.3 KiB · text History 1ce9641
pub mod local;

use async_trait::async_trait;
use std::path::PathBuf;

pub use local::LocalStorage;

#[derive(Debug, thiserror::Error)]
pub enum StorageError {
    #[error("io: {0}")]
    Io(#[from] std::io::Error),
}

/// Where in the backend a file lives. For local storage, this is the path
/// relative to STORAGE_ROOT — workers and the file server can resolve it
/// against their own root.
#[derive(Debug, Clone)]
pub struct StoredObject {
    pub relative_path: String,
    pub size_bytes: u64,
    pub sha256_hex: String,
}

#[async_trait]
pub trait Storage: Send + Sync {
    /// Persist `bytes` and return where it landed. Implementations should be
    /// content-addressed so identical bytes don't get duplicated.
    async fn put(&self, bytes: &[u8], extension: Option<&str>) -> Result<StoredObject, StorageError>;

    /// Resolve a relative path back to an absolute path on disk. Used by
    /// workers that need to read the original bytes (image processing, OCR).
    fn absolute_path(&self, relative: &str) -> PathBuf;

    /// Persist a derived artifact (thumbnail, etc.) at a deterministic
    /// sibling path. Returns the relative path used.
    async fn put_derived(
        &self,
        original_relative: &str,
        suffix: &str,
        bytes: &[u8],
    ) -> Result<String, StorageError>;
}