use std::error::Error as StdError;
use std::fmt;
use std::io;
use std::result;
use std::str;
use std::str::Utf8Error;
#[cold]
pub(crate) fn new_error(kind: ErrorKind) -> Error {
Error(Box::new(kind))
}
#[cold]
pub(crate) fn new_blob_error(kind: BlobError) -> Error {
Error(Box::new(ErrorKind::Blob(kind)))
}
#[cold]
pub(crate) fn new_wire_error(msg: &'static str) -> Error {
Error(Box::new(ErrorKind::WireFormat { msg }))
}
pub type Result<T> = result::Result<T, Error>;
#[derive(Debug)]
pub struct Error(Box<ErrorKind>);
impl Error {
#[inline]
pub fn kind(&self) -> &ErrorKind {
&self.0
}
#[inline]
pub fn into_kind(self) -> ErrorKind {
*self.0
}
}
#[non_exhaustive]
#[derive(Debug)]
pub enum ErrorKind {
Io(io::Error),
StringtableUtf8 { err: Utf8Error, index: usize },
StringtableIndexOutOfBounds { index: usize },
Blob(BlobError),
WireFormat { msg: &'static str },
MissingHeader,
}
#[non_exhaustive]
#[derive(Debug)]
pub enum BlobError {
InvalidHeaderSize,
HeaderTooBig {
size: u64,
},
MessageTooBig {
size: u64,
},
Empty,
InvalidDataSize {
size: i32,
},
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Error {
new_error(ErrorKind::Io(err))
}
}
impl From<protohoggr::WireError> for Error {
fn from(err: protohoggr::WireError) -> Error {
new_error(ErrorKind::WireFormat { msg: err.msg })
}
}
impl From<Error> for io::Error {
fn from(err: Error) -> io::Error {
io::Error::other(err)
}
}
impl StdError for Error {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
match *self.0 {
ErrorKind::Io(ref err) => Some(err),
ErrorKind::StringtableUtf8 { ref err, .. } => Some(err),
ErrorKind::StringtableIndexOutOfBounds { .. } => None,
ErrorKind::Blob(_) => None,
ErrorKind::WireFormat { .. } => None,
ErrorKind::MissingHeader => None,
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self.0 {
ErrorKind::Io(ref err) => err.fmt(f),
ErrorKind::StringtableUtf8 { ref err, index } => {
write!(f, "invalid UTF-8 at string table index {index}: {err}")
}
ErrorKind::StringtableIndexOutOfBounds { index } => {
write!(f, "stringtable index out of bounds: {index}")
}
ErrorKind::Blob(BlobError::InvalidHeaderSize) => {
write!(f, "blob header size could not be decoded")
}
ErrorKind::Blob(BlobError::HeaderTooBig { size }) => {
write!(f, "blob header is too big: {size} bytes")
}
ErrorKind::Blob(BlobError::MessageTooBig { size }) => {
write!(f, "blob message is too big: {size} bytes")
}
ErrorKind::Blob(BlobError::Empty) => {
write!(f, "blob is missing fields 'raw' and 'zlib_data'")
}
ErrorKind::Blob(BlobError::InvalidDataSize { size }) => {
write!(f, "blob header has negative datasize: {size}")
}
ErrorKind::WireFormat { msg } => {
write!(f, "wire format error: {msg}")
}
ErrorKind::MissingHeader => {
write!(f, "PBF file does not start with an OsmHeader blob")
}
}
}
}