use thiserror::Error;
#[derive(Debug, Error)]
pub enum PersistenceError {
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
#[error("format error: {0}")]
Format(String),
#[error("serialization error: {0}")]
Serialization(String),
#[error("deserialization error: {0}")]
Deserialization(String),
#[error("checksum mismatch: expected {expected}, got {actual}")]
ChecksumMismatch { expected: u32, actual: u32 },
#[error("failed to acquire lock on {resource}: {reason}")]
LockFailed { resource: String, reason: String },
#[error("invalid state: {0}")]
InvalidState(String),
#[error("resource not found: {0}")]
NotFound(String),
#[error("invalid configuration: {0}")]
InvalidConfig(String),
#[error("operation not supported: {0}")]
NotSupported(String),
#[error("distributed error: {0}")]
Distributed(String),
}
fn format_expected_actual(expected: &Option<String>, actual: &Option<String>) -> String {
match (expected, actual) {
(Some(e), Some(a)) => format!(" (expected: {}, actual: {})", e, a),
(Some(e), None) => format!(" (expected: {})", e),
(None, Some(a)) => format!(" (actual: {})", a),
(None, None) => String::new(),
}
}
#[cfg(feature = "persistence")]
impl From<postcard::Error> for PersistenceError {
fn from(e: postcard::Error) -> Self {
Self::Serialization(format!("postcard error: {}", e))
}
}
#[cfg(all(feature = "persistence", feature = "persistence-bincode"))]
impl From<bincode::Error> for PersistenceError {
fn from(e: bincode::Error) -> Self {
Self::Serialization(format!("bincode error (legacy): {}", e))
}
}
impl From<hiqlite::Error> for PersistenceError {
fn from(e: hiqlite::Error) -> Self {
Self::Distributed(e.to_string())
}
}
pub type PersistenceResult<T> = Result<T, PersistenceError>;