use std::error;
use std::fmt;
use std::io;
pub trait Context<T> {
fn context(self, msg: impl Into<String>) -> Result<T, Error>;
fn with_context<F, S>(self, cb: F) -> Result<T, Error>
where
F: Fn() -> S,
S: Into<String>;
}
impl<T, E: Into<ErrorKind>> Context<T> for Result<T, E> {
fn context(self, msg: impl Into<String>) -> Result<T, Error> {
self.map_err(|err| Error::new(msg, err))
}
fn with_context<F, S>(self, cb: F) -> Result<T, Error>
where
F: Fn() -> S,
S: Into<String>,
{
self.map_err(move |err| Error::new(cb(), err))
}
}
#[derive(Debug)]
pub struct Error {
msg: String,
kind: ErrorKind,
}
impl Error {
pub fn new(msg: impl Into<String>, kind: impl Into<ErrorKind>) -> Error {
Error {
msg: msg.into(),
kind: kind.into(),
}
}
pub fn kind(&self) -> &ErrorKind {
&self.kind
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.msg)
}
}
impl error::Error for Error {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match &self.kind {
ErrorKind::Internal => None,
ErrorKind::InvalidData => None,
ErrorKind::InvalidFont => None,
ErrorKind::PageSizeExceeded => None,
ErrorKind::UnsupportedEncoding => None,
ErrorKind::IoError(err) => Some(err),
ErrorKind::PdfError(err) => Some(err),
ErrorKind::PdfIndexError(err) => Some(err),
ErrorKind::RusttypeError(err) => Some(err),
#[cfg(feature = "images")]
ErrorKind::ImageError(err) => Some(err),
}
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum ErrorKind {
Internal,
InvalidData,
InvalidFont,
PageSizeExceeded,
UnsupportedEncoding,
IoError(io::Error),
PdfError(printpdf::PdfError),
PdfIndexError(printpdf::IndexError),
RusttypeError(rusttype::Error),
#[cfg(feature = "images")]
ImageError(image::ImageError),
}
impl From<io::Error> for ErrorKind {
fn from(error: io::Error) -> ErrorKind {
ErrorKind::IoError(error)
}
}
impl From<printpdf::Error> for ErrorKind {
fn from(error: printpdf::Error) -> ErrorKind {
match error {
printpdf::Error::Io(err) => err.into(),
printpdf::Error::Rusttype(err) => err.into(),
printpdf::Error::Pdf(err) => err.into(),
printpdf::Error::Index(err) => err.into(),
}
}
}
impl From<printpdf::IndexError> for ErrorKind {
fn from(error: printpdf::IndexError) -> ErrorKind {
ErrorKind::PdfIndexError(error)
}
}
impl From<printpdf::PdfError> for ErrorKind {
fn from(error: printpdf::PdfError) -> ErrorKind {
ErrorKind::PdfError(error)
}
}
impl From<rusttype::Error> for ErrorKind {
fn from(error: rusttype::Error) -> ErrorKind {
ErrorKind::RusttypeError(error)
}
}
#[cfg(feature = "images")]
impl From<image::ImageError> for ErrorKind {
fn from(error: image::ImageError) -> ErrorKind {
ErrorKind::ImageError(error)
}
}