use std::io; use std::path::PathBuf; use thiserror::Error; /// Result type for WAL operations. pub type Result = std::result::Result; /// Errors that can occur during WAL operations. #[derive(Error, Debug)] pub enum QuarantineError { /// IO error at a specific path. #[error("IO error at {path:?}: {source}")] Io { /// The path where the error occurred. path: PathBuf, /// The underlying IO error. source: io::Error, }, /// Failed to fsync a file. #[error("Failed to fsync {path:?}: {source}")] FsyncFailed { /// The path of the file. path: PathBuf, /// The underlying IO error. source: io::Error, }, /// File is locked by another process. #[error("File is locked: {path:?}")] FileLocked { /// The path of the locked file. path: PathBuf, }, /// CRC32C checksum mismatch (fast integrity check, detects torn writes). #[error( "CRC32C mismatch at offset {offset}: expected {expected:#010x}, actual {actual:#010x}" )] Crc32cMismatch { /// File offset where the corrupt record starts. offset: u64, /// Expected CRC32C value from the record header. expected: u32, /// Actual CRC32C computed from the data. actual: u32, }, /// Record length field is invalid (zero or exceeds MAX_RECORD_SIZE). #[error("Invalid record length at offset {offset}: {length} bytes")] InvalidRecordLength { /// File offset where the record starts. offset: u64, /// The invalid length value read. length: u32, }, /// Generic record corruption with a descriptive reason. #[error("Corrupt record at offset {offset}: {reason}")] CorruptRecord { /// File offset where corruption was detected. offset: u64, /// Human-readable description of the corruption. reason: String, }, /// Generic IO error. #[error(transparent)] IoGeneric(#[from] io::Error), } impl QuarantineError { /// Helper to create an `Io` error variant. pub fn io(path: impl Into, source: io::Error) -> Self { Self::Io { path: path.into(), source } } }