use std::fmt;
use thiserror::Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DbAdapterKind {
Generic,
Sqlx,
Diesel,
SeaOrm,
}
impl fmt::Display for DbAdapterKind {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(match self {
Self::Generic => "generic",
Self::Sqlx => "sqlx",
Self::Diesel => "diesel",
Self::SeaOrm => "seaorm",
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DbResultShape {
One,
Optional,
All,
Custom,
}
impl fmt::Display for DbResultShape {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(match self {
Self::One => "one",
Self::Optional => "optional",
Self::All => "all",
Self::Custom => "custom",
})
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DbOperationContext {
pub adapter: DbAdapterKind,
pub operation: String,
pub namespace: String,
pub physical_key: Option<String>,
pub result_shape: DbResultShape,
}
impl fmt::Display for DbOperationContext {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
let namespace = if self.namespace.is_empty() {
"<empty>"
} else {
&self.namespace
};
let physical_key = self.physical_key.as_deref().unwrap_or("<missing>");
write!(
formatter,
"adapter={}, namespace={}, key={}, result_shape={}",
self.adapter, namespace, physical_key, self.result_shape
)
}
}
#[derive(Debug, Error)]
pub enum DbCacheError {
#[error(
"database cached operation `{operation}` is missing an explicit cache key \
(adapter={adapter}, namespace={namespace}, result_shape={result_shape})"
)]
MissingKey {
operation: String,
adapter: DbAdapterKind,
namespace: String,
result_shape: DbResultShape,
},
#[error("database cached operation `{operation}` failed ({context}): {source}")]
Operation {
operation: String,
context: Box<DbOperationContext>,
#[source]
source: Box<hydracache::CacheError>,
},
#[error(transparent)]
Cache(#[from] hydracache::CacheError),
}
impl DbCacheError {
pub(crate) fn operation(context: DbOperationContext, source: hydracache::CacheError) -> Self {
Self::Operation {
operation: context.operation.clone(),
context: Box::new(context),
source: Box::new(source),
}
}
}
pub type Result<T> = std::result::Result<T, DbCacheError>;