use std::path::Path;
#[derive(Debug, thiserror::Error)]
pub enum StorageError {
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
#[error("Serialization error: {0}")]
Serialization(String),
#[error("Key not found")]
NotFound,
#[error("Storage corrupted: {0}")]
Corrupted(String),
#[error("Storage backend error: {0}")]
Backend(String),
}
pub type StorageResult<T> = Result<T, StorageError>;
pub trait StorageBackend: Send + Sync {
fn open(path: &Path) -> StorageResult<Self>
where
Self: Sized;
fn get(&self, key: &[u8]) -> StorageResult<Option<Vec<u8>>>;
fn set(&self, key: &[u8], value: &[u8]) -> StorageResult<()>;
fn delete(&self, key: &[u8]) -> StorageResult<()>;
fn contains(&self, key: &[u8]) -> StorageResult<bool> {
Ok(self.get(key)?.is_some())
}
fn flush(&self) -> StorageResult<()>;
fn scan_prefix(&self, prefix: &[u8]) -> StorageResult<Vec<(Vec<u8>, Vec<u8>)>>;
fn clear(&self) -> StorageResult<()>;
}
pub const SCHEMA_VERSION: u32 = 1;
pub mod keys {
pub const INVENTORY: &[u8] = b"inv:";
pub const DURATIONS: &[u8] = b"dur:";
pub const OUTCOMES: &[u8] = b"out:";
pub const CONTEXT: &[u8] = b"ctx:";
pub const SCHEMA: &[u8] = b"_schema_version";
}