use serde::{ de::{self, Visitor}, ser, Serialize, }; use serde_with::{DeserializeAs, SerializeAs}; use time::{macros::format_description, Date}; const YMD_FORMAT: &[time::format_description::FormatItem] = format_description!("[year]-[month]-[day]"); pub struct DateYmd; impl SerializeAs for DateYmd { fn serialize_as(date: &Date, serializer: S) -> Result where S: serde::Serializer, { date.format(YMD_FORMAT) .map_err(ser::Error::custom)? .serialize(serializer) } } impl<'de> DeserializeAs<'de, Date> for DateYmd { fn deserialize_as(deserializer: D) -> Result where D: serde::Deserializer<'de>, { struct DateYmdVisitor; impl<'de> Visitor<'de> for DateYmdVisitor { type Value = Date; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("a YYYY-MM-DD formatted date") } fn visit_str(self, v: &str) -> Result where E: serde::de::Error, { Date::parse(v, YMD_FORMAT).map_err(|_| { de::Error::invalid_value(de::Unexpected::Str(v), &"a YYYY-MM-DD formatted date") }) } } deserializer.deserialize_str(DateYmdVisitor) } }