caesura 0.19.0

An all-in-one command line tool to **transcode FLAC** audio files and **upload to gazelle** based indexers/trackers.
Documentation
use chrono::{DateTime, Utc};
use serde::de::{self, Visitor};
use serde::{Deserialize, Serialize};
use std::fmt;
use std::str::FromStr;

#[derive(Clone, Debug, PartialEq)]
pub struct TimeStamp {
    datetime: DateTime<Utc>,
}

impl TimeStamp {
    pub fn now() -> Self {
        TimeStamp {
            datetime: Utc::now(),
        }
    }

    #[allow(dead_code)]
    pub fn from_rfc3339(s: &str) -> Result<Self, chrono::ParseError> {
        let datetime = DateTime::parse_from_rfc3339(s)?.with_timezone(&Utc);
        Ok(TimeStamp { datetime })
    }
}

impl Serialize for TimeStamp {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let s = self
            .datetime
            .to_rfc3339_opts(chrono::SecondsFormat::Secs, true);
        serializer.serialize_str(&s)
    }
}

impl<'de> Deserialize<'de> for TimeStamp {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        struct TimeStampVisitor;

        impl<'de> Visitor<'de> for TimeStampVisitor {
            type Value = TimeStamp;
            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("a valid ISO 8601 date string")
            }
            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
            where
                E: de::Error,
            {
                let datetime = DateTime::from_str(value).map_err(de::Error::custom)?;
                Ok(TimeStamp { datetime })
            }
        }
        deserializer.deserialize_str(TimeStampVisitor)
    }
}