pdf_rs/error.rs
1use std::num::{ParseFloatError, ParseIntError};
2use std::string::FromUtf8Error;
3use crate::error::error_kind::{FLOAT_PARSE_ERROR, INT_PARSE_ERROR, INVALID_UTF8_STR, STD_IO_ERROR};
4
5/// Macro to define error kinds with codes and messages.
6///
7/// This macro generates a module containing error kind constants, each with a unique code and descriptive message.
8///
9/// # Arguments
10///
11/// * `$id` - The identifier for the error kind
12/// * `$code` - The numeric error code
13/// * `$message` - The descriptive error message
14macro_rules! error_kind {
15 ($(($id:ident,$code:literal,$message:literal)),+$(,)?) => {
16 /// Module containing error kind constants.
17 pub(crate) mod error_kind{
18 $(
19 /// Error kind constant with code and message.
20 pub(crate) const $id: super::Kind = ($code, $message);
21 )+
22 }
23 };
24}
25
26/// Type alias for error kind, consisting of a code and message.
27pub(crate) type Kind = (u16, &'static str);
28
29/// Type alias for results that may contain errors.
30pub type Result<T> = std::result::Result<T, Error>;
31
32/// Enumeration of all error kinds used in the PDF parser.
33error_kind!(
34 (INVALID_PDF_VERSION, 1000, "Invalid PDF version"),
35 (STD_IO_ERROR, 1001, "Std IO Error"),
36 (INVALID_PDF_FILE, 1002, "Invalid PDF file"),
37 (TRAILER_NOT_FOUND, 1003, "Trailer not found"),
38 (EOF, 1004, "End of file"),
39 (INVALID_UTF8_STR,1005, "Invalid UTF8 string"),
40 (INT_PARSE_ERROR,1006, "Int parse error"),
41 (INVALID_CROSS_TABLE_ENTRY,1007, "Invalid cross table entry"),
42 (TRAILER_EXCEPT_A_DICT,1008, "Trailer except a dict"),
43 (INVALID_NUMBER,1009, "Invalid number"),
44 (FLOAT_PARSE_ERROR,1010, "Float parse error"),
45 (EXCEPT_TOKEN,1011, "Except a token"),
46 (STR_NOT_ENCODED,1012, "String not encoded"),
47 (ILLEGAL_TOKEN,1013, "Illegal token"),
48 (INVALID_REAL_NUMBER,1014, "Invalid real number"),
49 (PARSE_UNSIGNED_VALUE_ERR,1015, "Parse unsigned value error"),
50 (SEEK_EXEED_MAX_SIZE,1016, "Seek exceed max size"),
51 (NO_XREF_TABLE_FOUND,1017, "No xref table found"),
52 (ILLEGAL_STREAM,1018, "Illegal stream"),
53 (EXCEPT_TRAILER,1019, "Except trailer"),
54 (CANT_FIND_ROOT,1020, "Can't find root"),
55 (PAGE_PARSE_ERROR,1021, "Page parse error"),
56);
57
58/// Inner structure holding error details.
59#[derive(Debug)]
60struct Inner {
61 /// Numeric error code.
62 pub code: u16,
63 /// Descriptive error message.
64 pub message: String,
65}
66
67/// Custom error type for PDF parsing operations.
68#[derive(Debug)]
69pub struct Error {
70 /// Inner error details.
71 inner: Inner,
72}
73
74impl Error {
75 /// Creates a new error with the specified kind and message.
76 ///
77 /// # Arguments
78 ///
79 /// * `kind` - The error kind containing code and base message
80 /// * `message` - The specific error message
81 ///
82 /// # Returns
83 ///
84 /// A new Error instance
85 pub(crate) fn new<T>(kind: Kind, message: T) -> Self where T: Into<String>{
86 let message = message.into();
87 Self {
88 inner: Inner {
89 code: kind.0,
90 message,
91 },
92 }
93 }
94}
95
96impl From<Kind> for Error {
97 /// Converts an error kind to an Error instance.
98 ///
99 /// # Arguments
100 ///
101 /// * `kind` - The error kind to convert
102 ///
103 /// # Returns
104 ///
105 /// An Error instance with the kind's code and message
106 fn from(kind: Kind) -> Self {
107 Self {
108 inner: Inner {
109 code: kind.0,
110 message: kind.1.to_string(),
111 },
112 }
113 }
114}
115
116impl From<std::io::Error> for Error {
117 /// Converts a standard IO error to a custom Error instance.
118 ///
119 /// # Arguments
120 ///
121 /// * `e` - The IO error to convert
122 ///
123 /// # Returns
124 ///
125 /// A custom Error instance with STD_IO_ERROR kind
126 fn from(e: std::io::Error) -> Self {
127 Self {
128 inner: Inner {
129 code: STD_IO_ERROR.0,
130 message: e.to_string(),
131 },
132 }
133 }
134}
135
136impl From<FromUtf8Error> for Error {
137 /// Converts a UTF-8 conversion error to a custom Error instance.
138 ///
139 /// # Arguments
140 ///
141 /// * `e` - The UTF-8 conversion error to convert
142 ///
143 /// # Returns
144 ///
145 /// A custom Error instance with INVALID_UTF8_STR kind
146 fn from(e: FromUtf8Error) -> Self {
147 Self {
148 inner: Inner {
149 code: INVALID_UTF8_STR.0,
150 message: e.to_string(),
151 },
152 }
153 }
154}
155
156impl From<ParseIntError> for Error{
157 /// Converts an integer parsing error to a custom Error instance.
158 ///
159 /// # Arguments
160 ///
161 /// * `e` - The integer parsing error to convert
162 ///
163 /// # Returns
164 ///
165 /// A custom Error instance with INT_PARSE_ERROR kind
166 fn from(e: ParseIntError) -> Self {
167 Self {
168 inner: Inner {
169 code: INT_PARSE_ERROR.0,
170 message: e.to_string(),
171 },
172 }
173 }
174}
175
176impl From<ParseFloatError> for Error {
177 /// Converts a float parsing error to a custom Error instance.
178 ///
179 /// # Arguments
180 ///
181 /// * `e` - The float parsing error to convert
182 ///
183 /// # Returns
184 ///
185 /// A custom Error instance with FLOAT_PARSE_ERROR kind
186 fn from(e: ParseFloatError) -> Self {
187
188 Self {
189 inner: Inner {
190 code: FLOAT_PARSE_ERROR.0,
191 message: e.to_string(),
192 },
193 }
194 }
195}