pdfplumber_parse/
error.rs1use pdfplumber_core::PdfError;
7use thiserror::Error;
8
9#[derive(Debug, Error)]
14pub enum BackendError {
15 #[error("PDF parse error: {0}")]
17 Parse(String),
18
19 #[error("I/O error: {0}")]
21 Io(#[from] std::io::Error),
22
23 #[error("font error: {0}")]
25 Font(String),
26
27 #[error("interpreter error: {0}")]
29 Interpreter(String),
30
31 #[error(transparent)]
33 Core(#[from] PdfError),
34}
35
36impl From<BackendError> for PdfError {
37 fn from(err: BackendError) -> Self {
38 match err {
39 BackendError::Parse(msg) => PdfError::ParseError(msg),
40 BackendError::Io(e) => PdfError::IoError(e.to_string()),
41 BackendError::Font(msg) => PdfError::FontError(msg),
42 BackendError::Interpreter(msg) => PdfError::InterpreterError(msg),
43 BackendError::Core(e) => e,
44 }
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn backend_error_parse() {
54 let err = BackendError::Parse("invalid xref table".to_string());
55 assert_eq!(err.to_string(), "PDF parse error: invalid xref table");
56 }
57
58 #[test]
59 fn backend_error_io_from_std() {
60 let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file missing");
61 let err: BackendError = io_err.into();
62 assert!(matches!(err, BackendError::Io(_)));
63 assert!(err.to_string().contains("file missing"));
64 }
65
66 #[test]
67 fn backend_error_from_pdf_error() {
68 let pdf_err = PdfError::FontError("bad metrics".to_string());
69 let err: BackendError = pdf_err.into();
70 assert!(matches!(err, BackendError::Core(_)));
71 }
72
73 #[test]
74 fn backend_error_to_pdf_error_parse() {
75 let backend = BackendError::Parse("bad syntax".to_string());
76 let pdf_err: PdfError = backend.into();
77 assert_eq!(pdf_err, PdfError::ParseError("bad syntax".to_string()));
78 }
79
80 #[test]
81 fn backend_error_to_pdf_error_io() {
82 let io_err = std::io::Error::new(std::io::ErrorKind::PermissionDenied, "denied");
83 let backend = BackendError::Io(io_err);
84 let pdf_err: PdfError = backend.into();
85 assert!(matches!(pdf_err, PdfError::IoError(_)));
86 assert!(pdf_err.to_string().contains("denied"));
87 }
88
89 #[test]
90 fn backend_error_to_pdf_error_font() {
91 let backend = BackendError::Font("missing widths".to_string());
92 let pdf_err: PdfError = backend.into();
93 assert_eq!(pdf_err, PdfError::FontError("missing widths".to_string()));
94 }
95
96 #[test]
97 fn backend_error_to_pdf_error_interpreter() {
98 let backend = BackendError::Interpreter("stack underflow".to_string());
99 let pdf_err: PdfError = backend.into();
100 assert_eq!(
101 pdf_err,
102 PdfError::InterpreterError("stack underflow".to_string())
103 );
104 }
105
106 #[test]
107 fn backend_error_to_pdf_error_core_passthrough() {
108 let original = PdfError::ResourceLimitExceeded("too large".to_string());
109 let backend = BackendError::Core(original.clone());
110 let pdf_err: PdfError = backend.into();
111 assert_eq!(pdf_err, original);
112 }
113
114 #[test]
115 fn backend_error_implements_std_error() {
116 let err: Box<dyn std::error::Error> = Box::new(BackendError::Parse("test".to_string()));
117 assert!(err.to_string().contains("test"));
118 }
119
120 #[test]
121 fn backend_error_core_password_required_passthrough() {
122 let backend = BackendError::Core(PdfError::PasswordRequired);
123 let pdf_err: PdfError = backend.into();
124 assert_eq!(pdf_err, PdfError::PasswordRequired);
125 }
126
127 #[test]
128 fn backend_error_core_invalid_password_passthrough() {
129 let backend = BackendError::Core(PdfError::InvalidPassword);
130 let pdf_err: PdfError = backend.into();
131 assert_eq!(pdf_err, PdfError::InvalidPassword);
132 }
133}