use std::fmt;
pub type OcrResult<T> = std::result::Result<T, OcrError>;
#[derive(Debug)]
pub enum OcrError {
ModelLoadError(String),
InferenceError(String),
InvalidImage(String),
PreprocessingError(String),
PostprocessingError(String),
DictionaryError(String),
NoTextDetected,
ConfigError(String),
IoError(std::io::Error),
}
impl fmt::Display for OcrError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
OcrError::ModelLoadError(msg) => write!(f, "Failed to load OCR model: {}", msg),
OcrError::InferenceError(msg) => write!(f, "OCR inference failed: {}", msg),
OcrError::InvalidImage(msg) => write!(f, "Invalid image for OCR: {}", msg),
OcrError::PreprocessingError(msg) => write!(f, "Image preprocessing failed: {}", msg),
OcrError::PostprocessingError(msg) => write!(f, "OCR postprocessing failed: {}", msg),
OcrError::DictionaryError(msg) => write!(f, "Character dictionary error: {}", msg),
OcrError::NoTextDetected => write!(f, "No text detected in image"),
OcrError::ConfigError(msg) => write!(f, "OCR configuration error: {}", msg),
OcrError::IoError(e) => write!(f, "I/O error: {}", e),
}
}
}
impl std::error::Error for OcrError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
OcrError::IoError(e) => Some(e),
_ => None,
}
}
}
impl From<std::io::Error> for OcrError {
fn from(err: std::io::Error) -> Self {
OcrError::IoError(err)
}
}
#[cfg(feature = "ocr")]
impl From<OcrError> for crate::Error {
fn from(err: OcrError) -> Self {
crate::Error::Ocr(err.to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display() {
let err = OcrError::ModelLoadError("model.onnx not found".to_string());
assert!(err.to_string().contains("model.onnx"));
}
#[test]
fn test_error_conversion() {
let ocr_err = OcrError::NoTextDetected;
let pdf_err: crate::Error = ocr_err.into();
assert!(pdf_err.to_string().contains("No text detected"));
}
}