use std::io;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum MappedFileError {
#[error("I/O error: {0}")]
Io(#[from] io::Error),
#[error("Out of bounds access: offset={offset}, size={size}, file_size={file_size}")]
OutOfBounds {
offset: usize,
size: usize,
file_size: u64,
},
#[error("File full: wrote={wrote}, capacity={capacity}")]
FileFull {
wrote: usize,
capacity: u64,
},
#[error("Memory mapping failed: {0}")]
MmapFailed(String),
#[error("Flush operation failed: {0}")]
FlushFailed(String),
#[error("Invalid file name: {0}")]
InvalidFileName(String),
#[error("File expansion failed: current_size={current_size}, requested_size={requested_size}")]
ExpansionFailed {
current_size: u64,
requested_size: u64,
},
#[error("Reference resource unavailable")]
ReferenceUnavailable,
#[error("Transient store pool exhausted")]
TransientStoreExhausted,
#[error("Configuration error: {0}")]
Configuration(String),
#[error("{0}")]
Custom(String),
}
pub type MappedFileResult<T> = Result<T, MappedFileError>;
impl MappedFileError {
#[inline]
pub fn out_of_bounds(offset: usize, size: usize, file_size: u64) -> Self {
Self::OutOfBounds {
offset,
size,
file_size,
}
}
#[inline]
pub fn file_full(wrote: usize, capacity: u64) -> Self {
Self::FileFull { wrote, capacity }
}
pub fn is_recoverable(&self) -> bool {
matches!(
self,
Self::OutOfBounds { .. } | Self::FileFull { .. } | Self::TransientStoreExhausted
)
}
pub fn is_io_error(&self) -> bool {
matches!(self, Self::Io(_))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_out_of_bounds_error() {
let err = MappedFileError::out_of_bounds(1000, 500, 1024);
assert!(err.is_recoverable());
assert!(err.to_string().contains("Out of bounds"));
}
#[test]
fn test_file_full_error() {
let err = MappedFileError::file_full(1024, 1024);
assert!(err.is_recoverable());
assert!(err.to_string().contains("File full"));
}
#[test]
fn test_io_error() {
let io_err = io::Error::new(io::ErrorKind::NotFound, "file not found");
let err = MappedFileError::from(io_err);
assert!(err.is_io_error());
}
#[test]
fn test_unrecoverable_error() {
let err = MappedFileError::MmapFailed("out of memory".to_string());
assert!(!err.is_recoverable());
}
}