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}