bunyan_view 0.3.3

A full-featured port of the Node Bunyan structured log file viewer
Documentation
use std::error::Error as StdError;
use std::num::ParseIntError;
use std::{fmt, str};

#[derive(Debug, Clone)]
pub struct LogLevelParseError {
    pub input: String,
}

impl From<String> for LogLevelParseError {
    fn from(s: String) -> Self {
        LogLevelParseError { input: s }
    }
}

impl fmt::Display for LogLevelParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "Unable to parse log level from input value: {}",
            self.input
        )
    }
}

impl StdError for LogLevelParseError {
    fn description(&self) -> &str {
        "Unable to parse log level from input value"
    }

    fn cause(&self) -> Option<&dyn StdError> {
        None // there is no causing error
    }
}

#[derive(Debug, Clone)]
pub struct BunyanLogParseError {
    msg: String,
}

impl BunyanLogParseError {
    pub fn new<S>(msg: S) -> BunyanLogParseError
    where
        S: Into<String>,
    {
        BunyanLogParseError { msg: msg.into() }
    }
}

impl fmt::Display for BunyanLogParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(self.msg.as_str())
    }
}

impl StdError for BunyanLogParseError {
    fn description(&self) -> &str {
        self.msg.as_str()
    }

    fn cause(&self) -> Option<&dyn StdError> {
        None // there is no causing error
    }
}

#[derive(Debug, Clone)]
pub enum ParseIntFromJsonError {
    Structural(BunyanLogParseError),
    Numeric(ParseIntError),
}

impl fmt::Display for ParseIntFromJsonError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ParseIntFromJsonError::Structural(ref e) => e.fmt(f),
            ParseIntFromJsonError::Numeric(ref e) => e.fmt(f),
        }
    }
}

impl StdError for ParseIntFromJsonError {
    fn cause(&self) -> Option<&dyn StdError> {
        match *self {
            ParseIntFromJsonError::Structural(ref e) => Some(e),
            ParseIntFromJsonError::Numeric(ref e) => Some(e),
        }
    }
}

pub type ParseResult = std::result::Result<(), BunyanLogParseError>;

pub struct Error {
    inner: Box<Inner>,
}

struct Inner {
    kind: Kind,
    line: String,
    line_no: usize,
    column: Option<usize>,
}

impl Error {
    pub fn new(kind: Kind, line: String, line_no: usize, column: Option<usize>) -> Error {
        Error {
            inner: Box::new(Inner {
                kind,
                line,
                line_no,
                column,
            }),
        }
    }

    #[inline]
    pub fn line(&self) -> &String {
        &self.inner.line
    }

    #[inline]
    pub fn line_no(&self) -> usize {
        self.inner.line_no
    }

    pub fn column(&self) -> Option<usize> {
        self.inner.column
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Error")
            .field("kind", &self.inner.kind)
            .field("line", &self.inner.line)
            .field("line_no", &self.inner.line_no)
            .field("column", &self.inner.column)
            .finish()
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.inner.kind {
            Kind::Json(ref e) => fmt::Display::fmt(e, f),
            Kind::BunyanLogParse(ref e) => fmt::Display::fmt(e, f),
        }
    }
}

impl StdError for Error {
    #[allow(deprecated)]
    fn cause(&self) -> Option<&dyn StdError> {
        match self.inner.kind {
            Kind::Json(ref e) => e.cause(),
            Kind::BunyanLogParse(ref e) => e.cause(),
        }
    }
}

#[derive(Debug)]
pub enum Kind {
    BunyanLogParse(BunyanLogParseError),
    Json(::serde_json::Error),
}

impl From<BunyanLogParseError> for Kind {
    #[inline]
    fn from(error: BunyanLogParseError) -> Kind {
        Kind::BunyanLogParse(error)
    }
}

impl From<::serde_json::Error> for Kind {
    #[inline]
    fn from(error: ::serde_json::Error) -> Kind {
        Kind::Json(error)
    }
}