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);
}
}