use std::{fmt, io, result};
use std::error::Error;
#[derive(Debug)]
pub struct SerializerError(Box<RawSerializerError>);
#[derive(Debug)]
struct RawSerializerError {
kind: SerializerErrorKind,
source: Option<Box<dyn std::error::Error + Send + Sync>>,
}
impl SerializerError {
pub(crate) fn io<E>(error: E) -> Self
where E: Into<Box<dyn std::error::Error + Send + Sync>> {
Self(Box::new(RawSerializerError {
kind: SerializerErrorKind::Io,
source: Some(error.into()),
}))
}
pub(crate) fn syntax<E>(error: E) -> Self
where E: Into<Box<dyn std::error::Error + Send + Sync>> {
Self(Box::new(RawSerializerError {
kind: SerializerErrorKind::Syntax,
source: Some(error.into()),
}))
}
#[allow(dead_code)]
pub(crate) fn other<E>(error: E) -> Self
where E: Into<Box<dyn std::error::Error + Send + Sync>> {
Self(Box::new(RawSerializerError {
kind: SerializerErrorKind::Other,
source: Some(error.into()),
}))
}
pub fn kind(&self) -> SerializerErrorKind {
self.0.kind
}
pub fn is_io(&self) -> bool {
SerializerErrorKind::Io == self.0.kind
}
pub fn is_syntax(&self) -> bool {
SerializerErrorKind::Syntax == self.0.kind
}
pub fn is_other(&self) -> bool {
SerializerErrorKind::Other == self.0.kind
}
}
impl Error for SerializerError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self.0.source {
Some(ref source) => Some(&**source),
None => None
}
}
}
impl fmt::Display for SerializerError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.kind.fmt(f)
}
}
impl From<io::Error> for SerializerError {
fn from(error: io::Error) -> Self {
Self::io(error)
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum SerializerErrorKind {
Syntax,
Io,
Other,
}
impl fmt::Display for SerializerErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use SerializerErrorKind::*;
match self {
Syntax => write!(f, "invalid syntax"),
Io => write!(f, "io error"),
Other => write!(f, "other error"),
}
}
}
pub type Result<T> = result::Result<T, SerializerError>;