use std::fmt;
use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};
use serde::{Deserialize, Deserializer, de::{self, Visitor}};
struct DateVisitor;
impl<'de> Visitor<'de> for DateVisitor {
type Value = DateTime<Utc>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string for a date in format 1900-01-01 00:00:00(.000000)")
}
fn visit_str<E>(self, value: &str) -> Result<DateTime<Utc>, E>
where
E: de::Error,
{
let (date, _remainder) = NaiveDateTime::parse_and_remainder(value, "%F %T%.f")
.map_err(|e| {
eprintln!("Unable to format {value}: {:?}", e);
de::Error::custom(e)
})?;
Ok(date.and_utc())
}
}
pub fn date_from_str<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_identifier(DateVisitor) }
struct OptionDateVisitor;
impl<'de> Visitor<'de> for OptionDateVisitor {
type Value = Option<DateTime<Utc>>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string for a date in format 1900-01-01 00:00:00(.000000) or null (undefined)")
}
fn visit_none<E>(self) -> Result<Option<DateTime<Utc>>, E>
where
E: de::Error,
{
Ok(None)
}
fn visit_some<D>(self, deserializer: D) -> Result<Option<DateTime<Utc>>, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(DateVisitor).map(Some)
}
}
pub fn option_date_from_str<'de, D>(deserializer: D) -> Result<Option<DateTime<Utc>>, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_option(OptionDateVisitor)
}
struct SmallDateVisitor;
impl<'de> Visitor<'de> for SmallDateVisitor {
type Value = DateTime<Utc>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string for a date in format 1900-01-01)")
}
fn visit_str<E>(self, value: &str) -> Result<DateTime<Utc>, E>
where
E: de::Error,
{
let (date, _remainder) = NaiveDate::parse_and_remainder(value, "%F")
.map_err(|e| {
eprintln!("Unable to format {value}: {:?}", e);
de::Error::custom(e)
})?;
Ok(date.and_time(NaiveTime::default()).and_utc())
}
}
pub fn small_date_from_str<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_identifier(SmallDateVisitor) }
pub fn empty_object_as_empty_array<'de, T, D>(deserializer: D) -> Result<Vec<T>, D::Error>
where
T: Deserialize<'de>,
D: Deserializer<'de>,
{
struct EmptyObjectAsEmptyArrayVisitor<T> {
marker: std::marker::PhantomData<T>,
}
impl<'de, T> Visitor<'de> for EmptyObjectAsEmptyArrayVisitor<T>
where
T: Deserialize<'de>,
{
type Value = Vec<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an empty object or an array")
}
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Vec::new())
}
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
where
M: serde::de::MapAccess<'de>,
{
if map.next_key::<T>()?.is_none() {
Ok(Vec::new())
} else {
Err(de::Error::custom("expected an empty object"))
}
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let mut vec = Vec::new();
while let Some(item) = seq.next_element()? {
vec.push(item);
}
Ok(vec)
}
}
deserializer.deserialize_any(EmptyObjectAsEmptyArrayVisitor {
marker: std::marker::PhantomData,
})
}