use super::def_serde_traits_for;
use std::str::FromStr;
#[cfg(not(feature = "chrono"))]
type InnerDateTime = String;
#[cfg(feature = "chrono")]
type InnerDateTime = ::chrono::DateTime<::chrono::FixedOffset>;
#[allow(missing_copy_implementations)]
#[derive(Clone, Debug, PartialEq)]
pub struct DateTime2822(InnerDateTime);
def_serde_traits_for!(DateTime2822);
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum DateTime2822ParseError {
#[cfg(feature = "chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
InvalidDate(::chrono::ParseError),
}
crate::errors::error_enum!(DateTime2822ParseError);
#[cfg(not(feature = "chrono"))]
mod not_chrono {
use super::*;
impl FromStr for DateTime2822 {
type Err = DateTime2822ParseError;
fn from_str(when: &str) -> Result<Self, Self::Err> {
Ok(Self(when.to_owned()))
}
}
impl std::fmt::Display for DateTime2822 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "{}", self.0)
}
}
}
#[cfg(feature = "chrono")]
mod chrono {
use super::*;
use ::chrono::{DateTime, FixedOffset};
impl FromStr for DateTime2822 {
type Err = DateTime2822ParseError;
fn from_str(when: &str) -> Result<Self, Self::Err> {
let when = when.replace("UTC", "UT");
Ok(Self(
DateTime::parse_from_rfc2822(&when).map_err(DateTime2822ParseError::InvalidDate)?,
))
}
}
impl std::fmt::Display for DateTime2822 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "{}", self.0)
}
}
impl DateTime2822 {
#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
pub fn to_datetime(&self) -> &DateTime<FixedOffset> {
&self.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_date_time_chrono_parse() {
let _: DateTime2822 = "Mon, 26 Dec 2022 16:30:00 +0100".parse().unwrap();
}
#[test]
fn test_date_time_chrono_wont_parse() {
assert!(
"Tue, 26 Dec 2022 16:30:00 +0100"
.parse::<DateTime2822>()
.is_err()
);
}
}
}