use async_trait::async_trait;
use serde_json::json;
#[async_trait]
pub trait ApqStorage: Send + Sync {
async fn get(&self, hash: &str) -> Result<Option<String>, ApqError>;
async fn set(&self, hash: String, query: String) -> Result<(), ApqError>;
async fn exists(&self, hash: &str) -> Result<bool, ApqError>;
async fn remove(&self, hash: &str) -> Result<(), ApqError>;
async fn stats(&self) -> Result<ApqStats, ApqError>;
async fn clear(&self) -> Result<(), ApqError>;
}
#[derive(Debug, Clone)]
pub struct ApqStats {
pub total_queries: usize,
pub backend: String,
pub extra: serde_json::Value,
}
impl ApqStats {
#[must_use]
pub fn new(total_queries: usize, backend: String) -> Self {
Self {
total_queries,
backend,
extra: json!({}),
}
}
#[must_use]
pub const fn with_extra(
total_queries: usize,
backend: String,
extra: serde_json::Value,
) -> Self {
Self {
total_queries,
backend,
extra,
}
}
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum ApqError {
#[error("Query not found")]
NotFound,
#[error("Query size exceeds maximum limit (100KB)")]
QueryTooLarge,
#[error("Storage error: {0}")]
StorageError(String),
#[error("Serialization error: {0}")]
SerializationError(String),
#[error("Database error: {0}")]
DatabaseError(String),
#[error("Configuration error: {0}")]
ConfigError(String),
}
pub type ArcApqStorage = std::sync::Arc<dyn ApqStorage>;