use crate::types::PageId;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("page {0} failed MAC verification: data has been tampered with")]
PageTampered(PageId),
#[error("incorrect passphrase or wrong key file")]
BadPassphrase,
#[error("database file is locked by another process")]
DatabaseLocked,
#[error("key file does not match data file (file_id mismatch)")]
KeyFileMismatch,
#[error("transaction requires more pages than buffer pool capacity ({capacity})")]
TransactionTooLarge { capacity: usize },
#[error("database file is corrupted: both commit slots are invalid")]
DatabaseCorrupted,
#[error("page checksum mismatch on page {0} (post-decrypt integrity failure)")]
ChecksumMismatch(PageId),
#[error("invalid page type {0} on page {1}")]
InvalidPageType(u16, PageId),
#[error("key too large: {size} bytes (max {max})")]
KeyTooLarge { size: usize, max: usize },
#[error("value too large: {size} bytes (max {max})")]
ValueTooLarge { size: usize, max: usize },
#[error("invalid magic number: expected 0x{expected:08X}, found 0x{found:08X}")]
InvalidMagic { expected: u32, found: u32 },
#[error("unsupported format version: {0}")]
UnsupportedVersion(u32),
#[error("key file integrity check failed (HMAC mismatch)")]
KeyFileIntegrity,
#[error("invalid key file magic")]
InvalidKeyFileMagic,
#[error("key unwrap failed (AES-KW integrity check)")]
KeyUnwrapFailed,
#[error("no write transaction active")]
NoWriteTransaction,
#[error("a write transaction is already active")]
WriteTransactionActive,
#[error("page {0} is out of bounds (beyond high water mark)")]
PageOutOfBounds(PageId),
#[error("buffer pool is full and all pages are pinned")]
BufferPoolFull,
#[error("unsupported cipher: {0}")]
UnsupportedCipher(u8),
#[error("unsupported KDF algorithm: {0}")]
UnsupportedKdf(u8),
#[error("FIPS mode violation: {0}")]
FipsViolation(String),
#[error("table not found: {0}")]
TableNotFound(String),
#[error("table already exists: {0}")]
TableAlreadyExists(String),
#[error("passphrase is required")]
PassphraseRequired,
#[error("sync error: {0}")]
Sync(String),
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn error_display() {
let e = Error::PageTampered(PageId(42));
assert!(format!("{e}").contains("page:42"));
let e = Error::TransactionTooLarge { capacity: 256 };
assert!(format!("{e}").contains("256"));
}
#[test]
fn error_from_io() {
let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
let e: Error = io_err.into();
assert!(matches!(e, Error::Io(_)));
}
}