simple-datetime-rs 0.3.0

A high-performance, lightweight date and time library for Rust with dramatically faster parsing, memory-efficient operations, and chrono-compatible formatting
Documentation
use std::{error::Error, fmt};

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum DateErrorKind {
    WrongDateStringFormat,
    WrongTimeStringFormat,
    WrongDateTimeStringFormat,
    WrongTimeShiftStringFormat,
    Inner,
}

#[derive(Debug)]
pub struct DateError {
    pub source: Option<Box<dyn Error>>,
    pub kind: DateErrorKind,
}

impl DateError {
    pub fn new_inner(source: Box<dyn Error>) -> Self {
        DateError {
            source: Some(source),
            kind: DateErrorKind::Inner,
        }
    }

    pub fn new_kind(kind: DateErrorKind) -> Self {
        DateError { source: None, kind }
    }
}

impl Error for DateError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        self.source.as_deref()
    }
}

impl fmt::Display for DateErrorKind {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            DateErrorKind::WrongDateStringFormat => write!(f, "wrong date format"),
            DateErrorKind::WrongTimeStringFormat => write!(f, "wrong time format"),
            DateErrorKind::WrongDateTimeStringFormat => write!(f, "wrong datetime format"),
            DateErrorKind::WrongTimeShiftStringFormat => write!(f, "wrong time shift format"),
            DateErrorKind::Inner => write!(f, "error in DateError::source"),
        }
    }
}

impl fmt::Display for DateError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.kind)
    }
}

impl From<DateErrorKind> for DateError {
    fn from(kind: DateErrorKind) -> Self {
        Self::new_kind(kind)
    }
}

impl From<Box<dyn Error>> for DateError {
    fn from(err: Box<dyn Error>) -> Self {
        Self::new_inner(err)
    }
}

impl DateErrorKind {
    pub fn into_boxed_error(self) -> Box<dyn Error> {
        let error: DateError = self.into();
        error.into()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::io;

    #[test]
    fn test_date_error_kind_display() {
        assert_eq!(
            DateErrorKind::WrongDateStringFormat.to_string(),
            "wrong date format"
        );
        assert_eq!(
            DateErrorKind::WrongTimeStringFormat.to_string(),
            "wrong time format"
        );
        assert_eq!(
            DateErrorKind::WrongDateTimeStringFormat.to_string(),
            "wrong datetime format"
        );
        assert_eq!(
            DateErrorKind::WrongTimeShiftStringFormat.to_string(),
            "wrong time shift format"
        );
        assert_eq!(
            DateErrorKind::Inner.to_string(),
            "error in DateError::source"
        );
    }

    #[test]
    fn test_date_error_display() {
        let error = DateError::new_kind(DateErrorKind::WrongDateStringFormat);
        assert_eq!(error.to_string(), "wrong date format");

        let error2 = DateError::new_kind(DateErrorKind::WrongTimeStringFormat);
        assert_eq!(error2.to_string(), "wrong time format");
    }

    #[test]
    fn test_date_error_with_source() {
        let io_error = io::Error::new(io::ErrorKind::InvalidInput, "test error");
        let date_error = DateError::new_inner(Box::new(io_error));

        assert!(date_error.source().is_some());
        assert_eq!(date_error.kind, DateErrorKind::Inner);
    }

    #[test]
    fn test_date_error_from_kind() {
        let error: DateError = DateErrorKind::WrongDateStringFormat.into();
        assert_eq!(error.kind, DateErrorKind::WrongDateStringFormat);
        assert!(error.source().is_none());
    }

    #[test]
    fn test_date_error_from_boxed_error() {
        let io_error = io::Error::new(io::ErrorKind::InvalidInput, "test error");
        let date_error: DateError = (Box::new(io_error) as Box<dyn Error>).into();

        assert_eq!(date_error.kind, DateErrorKind::Inner);
        assert!(date_error.source().is_some());
    }

    #[test]
    fn test_date_error_kind_into_boxed_error() {
        let boxed_error = DateErrorKind::WrongDateStringFormat.into_boxed_error();
        assert!(boxed_error.is::<DateError>());
    }

    #[test]
    fn test_date_error_constructors() {
        let error1 = DateError::new_kind(DateErrorKind::WrongTimeStringFormat);
        assert_eq!(error1.kind, DateErrorKind::WrongTimeStringFormat);
        assert!(error1.source().is_none());

        let io_error = io::Error::new(io::ErrorKind::InvalidInput, "test");
        let error2 = DateError::new_inner(Box::new(io_error));
        assert_eq!(error2.kind, DateErrorKind::Inner);
        assert!(error2.source().is_some());
    }

    #[test]
    fn test_date_error_debug() {
        let error = DateError::new_kind(DateErrorKind::WrongDateStringFormat);
        let debug_str = format!("{:?}", error);
        assert!(debug_str.contains("DateError"));
    }

    #[test]
    fn test_date_error_kind_debug() {
        let kind = DateErrorKind::WrongTimeStringFormat;
        let debug_str = format!("{:?}", kind);
        assert!(debug_str.contains("WrongTimeStringFormat"));
    }

    #[test]
    fn test_date_error_kind_access() {
        let error = DateError::new_kind(DateErrorKind::WrongDateTimeStringFormat);
        assert_eq!(error.kind, DateErrorKind::WrongDateTimeStringFormat);
    }

    #[test]
    fn test_date_error_kind_clone() {
        let kind = DateErrorKind::WrongTimeShiftStringFormat;
        let cloned_kind = kind.clone();
        assert_eq!(kind, cloned_kind);
    }
}