use crate::osm_io::error::ErrorKind::IO;
use crate::osm_io::error::Repr::Simple;
use std::fmt::{Display, Formatter};
use std::io;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
pub struct Error {
repr: Repr,
message: Option<String>,
}
#[derive(Debug)]
enum Repr {
Simple(ErrorKind),
}
#[derive(Debug)]
pub enum ErrorKind {
InvalidFileFormat,
ParseError,
IO(io::Error),
}
impl Error {
pub fn new(kind: ErrorKind, message: Option<String>) -> Self {
Error {
repr: Simple(kind),
message,
}
}
pub fn message(&self) -> Option<&String> {
self.message.as_ref()
}
pub fn set_message(&mut self, message: String) {
self.message = Some(message);
}
pub fn kind(&self) -> &ErrorKind {
match &self.repr {
Simple(e) => &e,
}
}
}
impl ErrorKind {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
IO(e) => Some(e),
_ => None,
}
}
}
impl Display for ErrorKind {
fn fmt(&self, f: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
match self {
ErrorKind::InvalidFileFormat => write!(f, "File format not recognized.")?,
ErrorKind::ParseError => write!(f, "Unknown parse error occurred.")?,
IO(io_error) => match io_error.kind() {
io::ErrorKind::UnexpectedEof => write!(f, "Unexpected end of file.")?,
_ => write!(f, "IO error: {}", io_error)?,
},
};
Ok(())
}
}
impl Repr {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Simple(kind) => kind.source(),
}
}
}
impl Display for Repr {
fn fmt(&self, f: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
let Simple(kind) = self;
kind.fmt(f)
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.repr.source()
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
match &self.message {
Some(message) => write!(f, "{}", message),
None => self.repr.fmt(f),
}
}
}
impl PartialEq for Error {
fn eq(&self, _other: &Self) -> bool {
false
}
}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Self {
Error {
repr: Simple(IO(e)),
message: None,
}
}
}