//! Formatting error(s). use super::*; use std::{ error, fmt, }; /// A formatting error kind. See `Error`. #[derive(Debug)] pub enum ErrorKind { IO(io::Error), Json(serde_json::Error), Cbor(serde_cbor::Error), Lexpr(serde_lexpr::Error), Unknown, } impl From for ErrorKind { fn from(from: io::Error) -> Self { Self::IO(from) } } impl From for ErrorKind { fn from(from: serde_json::Error) -> Self { Self::Json(from) } } impl From for ErrorKind { fn from(from: serde_cbor::Error) -> Self { Self::Cbor(from) } } impl From for ErrorKind { fn from(from: serde_lexpr::Error) -> Self { Self::Lexpr(from) } } /// A formatting error. #[derive(Debug)] pub struct Error(Box, bool); impl Error { /// An encode error #[inline] pub fn encode(kind: impl Into) -> Self { Self(Box::new(kind.into()), true) } /// A decode error #[inline] pub fn decode(kind: impl Into) -> Self { Self(Box::new(kind.into()), false) } /// What kind of error was it? #[inline] pub fn kind(&self) -> &ErrorKind { &self.0 } /// Consume into the kind of error, which contains the original error object from the conversion (if there is one) #[inline] pub fn into_inner(self) -> ErrorKind { *self.0 } /// Is an encode error? #[inline] pub fn is_encode(&self) -> bool { self.1 } /// Is a decode error? #[inline] pub fn is_decode(&self) -> bool { !self.1 } } impl error::Error for Error { fn source(&self) -> Option<&(dyn error::Error + 'static)> { Some(match self.0.as_ref() { ErrorKind::IO(i) => i, ErrorKind::Json(i) => i, ErrorKind::Cbor(i) => i, ErrorKind::Lexpr(i) => i, _ => return None, }) } } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "formatting error in ")?; if self.1 { write!(f, "encode") } else { write!(f, "decode") } } } impl From<(io::Error, bool)> for Error { #[inline] fn from(from: (io::Error, bool)) -> Self { Self(Box::new(ErrorKind::IO(from.0)), from.1) } } impl From for io::Error { fn from(from: Error) -> Self { match *from.0 { ErrorKind::IO(io) => io, _ => io::Error::new(io::ErrorKind::Other, from), } } }