1use core::num::TryFromIntError;
21use std::error::Error;
22use std::string::FromUtf8Error;
23use std::{cell, io, result, str};
24
25#[cfg(feature = "arrow")]
26use arrow_schema::ArrowError;
27
28#[derive(Debug)]
32#[non_exhaustive]
33pub enum ParquetError {
34 General(String),
37 NYI(String),
40 EOF(String),
44 #[cfg(feature = "arrow")]
45 ArrowError(String),
48 IndexOutOfBound(usize, usize),
51 External(Box<dyn Error + Send + Sync>),
53 NeedMoreData(usize),
56 NeedMoreDataRange(std::ops::Range<u64>),
59}
60
61impl std::fmt::Display for ParquetError {
62 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
63 match &self {
64 ParquetError::General(message) => {
65 write!(fmt, "Parquet error: {message}")
66 }
67 ParquetError::NYI(message) => write!(fmt, "NYI: {message}"),
68 ParquetError::EOF(message) => write!(fmt, "EOF: {message}"),
69 #[cfg(feature = "arrow")]
70 ParquetError::ArrowError(message) => write!(fmt, "Arrow: {message}"),
71 ParquetError::IndexOutOfBound(index, bound) => {
72 write!(fmt, "Index {index} out of bound: {bound}")
73 }
74 ParquetError::External(e) => write!(fmt, "External: {e}"),
75 ParquetError::NeedMoreData(needed) => write!(fmt, "NeedMoreData: {needed}"),
76 ParquetError::NeedMoreDataRange(range) => {
77 write!(fmt, "NeedMoreDataRange: {}..{}", range.start, range.end)
78 }
79 }
80 }
81}
82
83impl Error for ParquetError {
84 fn source(&self) -> Option<&(dyn Error + 'static)> {
85 match self {
86 ParquetError::External(e) => Some(e.as_ref()),
87 _ => None,
88 }
89 }
90}
91
92impl From<TryFromIntError> for ParquetError {
93 fn from(e: TryFromIntError) -> ParquetError {
94 ParquetError::General(format!("Integer overflow: {e}"))
95 }
96}
97
98impl From<io::Error> for ParquetError {
99 fn from(e: io::Error) -> ParquetError {
100 ParquetError::External(Box::new(e))
101 }
102}
103
104#[cfg(any(feature = "snap", test))]
105impl From<snap::Error> for ParquetError {
106 fn from(e: snap::Error) -> ParquetError {
107 ParquetError::External(Box::new(e))
108 }
109}
110
111impl From<thrift::Error> for ParquetError {
112 fn from(e: thrift::Error) -> ParquetError {
113 ParquetError::External(Box::new(e))
114 }
115}
116
117impl From<cell::BorrowMutError> for ParquetError {
118 fn from(e: cell::BorrowMutError) -> ParquetError {
119 ParquetError::External(Box::new(e))
120 }
121}
122
123impl From<str::Utf8Error> for ParquetError {
124 fn from(e: str::Utf8Error) -> ParquetError {
125 ParquetError::External(Box::new(e))
126 }
127}
128
129impl From<FromUtf8Error> for ParquetError {
130 fn from(e: FromUtf8Error) -> ParquetError {
131 ParquetError::External(Box::new(e))
132 }
133}
134
135#[cfg(feature = "arrow")]
136impl From<ArrowError> for ParquetError {
137 fn from(e: ArrowError) -> ParquetError {
138 ParquetError::External(Box::new(e))
139 }
140}
141
142#[cfg(feature = "object_store")]
143impl From<object_store::Error> for ParquetError {
144 fn from(e: object_store::Error) -> ParquetError {
145 ParquetError::External(Box::new(e))
146 }
147}
148
149#[cfg(feature = "encryption")]
150impl From<ring::error::Unspecified> for ParquetError {
151 fn from(e: ring::error::Unspecified) -> ParquetError {
152 ParquetError::External(Box::new(e))
153 }
154}
155
156pub type Result<T, E = ParquetError> = result::Result<T, E>;
158
159impl From<ParquetError> for io::Error {
163 fn from(e: ParquetError) -> Self {
164 io::Error::other(e)
165 }
166}
167
168macro_rules! general_err {
172 ($fmt:expr) => (ParquetError::General($fmt.to_owned()));
173 ($fmt:expr, $($args:expr),*) => (ParquetError::General(format!($fmt, $($args),*)));
174 ($e:expr, $fmt:expr) => (ParquetError::General($fmt.to_owned(), $e));
175 ($e:ident, $fmt:expr, $($args:tt),*) => (
176 ParquetError::General(&format!($fmt, $($args),*), $e));
177}
178
179macro_rules! nyi_err {
180 ($fmt:expr) => (ParquetError::NYI($fmt.to_owned()));
181 ($fmt:expr, $($args:expr),*) => (ParquetError::NYI(format!($fmt, $($args),*)));
182}
183
184macro_rules! eof_err {
185 ($fmt:expr) => (ParquetError::EOF($fmt.to_owned()));
186 ($fmt:expr, $($args:expr),*) => (ParquetError::EOF(format!($fmt, $($args),*)));
187}
188
189#[cfg(feature = "arrow")]
190macro_rules! arrow_err {
191 ($fmt:expr) => (ParquetError::ArrowError($fmt.to_owned()));
192 ($fmt:expr, $($args:expr),*) => (ParquetError::ArrowError(format!($fmt, $($args),*)));
193 ($e:expr, $fmt:expr) => (ParquetError::ArrowError($fmt.to_owned(), $e));
194 ($e:ident, $fmt:expr, $($args:tt),*) => (
195 ParquetError::ArrowError(&format!($fmt, $($args),*), $e));
196}
197
198#[cfg(feature = "arrow")]
202impl From<ParquetError> for ArrowError {
203 fn from(p: ParquetError) -> Self {
204 Self::ParquetError(format!("{p}"))
205 }
206}