use std::error;
use std::fmt::{self, Debug, Display};
use std::result;
use serde::ser;
pub struct Error {
pub(crate) err: Box<ErrorImpl>, }
pub type Result<T> = result::Result<T, Error>;
#[derive(Debug)]
pub(crate) struct ErrorImpl {
pub(crate) code: ErrorCode,
pub(crate) line: usize,
pub(crate) column: usize,
}
#[derive( Clone, Debug, PartialEq, Eq, PartialOrd, Ord )]
pub(crate) enum ErrorCode {
Unknown,
Serde( String ),
UnsupportedEscape( char ),
HeaderMistach,
InvalidConfig,
ExtraColumns,
ExpectedChar,
ExpectedBoolean,
ExpectedUnsigned,
ExpectedInteger,
ExpectedFloat,
ExpectedUnit,
ExpectedVariant,
}
impl Error {
pub(crate) fn new( code: ErrorCode, line: usize, column: usize ) -> Self {
Error{ err: Box::new( ErrorImpl{ code, line, column })}
}
pub fn line( &self ) -> usize { self.err.line }
pub fn column( &self ) -> usize { self.err.column }
}
impl error::Error for Error {
fn description(&self) -> &str {
"TSV error"
}
fn cause(&self) -> Option<&error::Error> {
None
}
}
impl Display for Error {
fn fmt( &self, f: &mut fmt::Formatter ) -> fmt::Result {
Display::fmt( &*self.err, f )
}
}
impl Display for ErrorImpl {
fn fmt( &self, f: &mut fmt::Formatter ) -> fmt::Result {
if self.line == 0 {
Debug::fmt( &self.code, f )
} else {
write!(
f,
"{:?} at line {} column {}",
self.code,
self.line,
self.column
)
}
}
}
impl Debug for Error {
fn fmt( &self, f: &mut fmt::Formatter ) -> fmt::Result {
Debug::fmt( &*self.err, f )
}
}
impl ser::Error for Error {
fn custom<T:Display>( _msg: T ) -> Error {
Error {
err: Box::new(
ErrorImpl {
code: ErrorCode::Unknown,
line: 0,
column: 0,
},
),
}
}
}
impl ::serde::de::Error for Error {
fn custom<T:Display>( msg: T ) -> Error {
Error {
err: Box::new(
ErrorImpl {
code: ErrorCode::Serde( msg.to_string() ),
line: 0,
column: 0,
},
),
}
}
fn invalid_type( unexp: ::serde::de::Unexpected, exp: &::serde::de::Expected ) -> Self {
if let ::serde::de::Unexpected::Unit = unexp {
Error::custom( format_args!( "invalid type: null, expected {}", exp ))
} else {
Error::custom( format_args!( "invalid type: {}, expected {}", unexp, exp ))
}
}
}