dodo 0.3.1

Basic persistence library designed to be a quick and easy way to create a persistent storage.
Documentation
use std::{fmt, io, result};
use std::error::Error;

/// Serializer 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()),
        }))
    }

    /// Error kind.
    pub fn kind(&self) -> SerializerErrorKind {
        self.0.kind
    }

    /// Returns true if this error is Io.
    pub fn is_io(&self) -> bool {
        SerializerErrorKind::Io == self.0.kind
    }

    /// Returns true if this error Syntax.
    pub fn is_syntax(&self) -> bool {
        SerializerErrorKind::Syntax == self.0.kind
    }

    /// Returns true if this error is Other.
    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)
    }
}

/// Serializer error kind.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum SerializerErrorKind {
    /// Invalid Syntax.
    Syntax,
    /// Io error (unexpected EOF, interrupted, ...).
    Io,
    /// Other error.
    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"),
        }
    }
}

/// Serializer result.
pub type Result<T> = result::Result<T, SerializerError>;