use chrono::{DateTime, Utc}; use serde::{Deserialize, Deserializer, Serializer}; /// Serialize/deserialize `DateTime` as BSON DateTime. /// Handles both BSON DateTime objects and RFC 3339 strings on deserialization. pub mod bson_datetime { use super::*; use serde::Serialize as _; pub fn serialize(dt: &DateTime, serializer: S) -> Result where S: Serializer, { let bson_dt: bson::DateTime = (*dt).into(); bson_dt.serialize(serializer) } pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { let bson_val = bson::Bson::deserialize(deserializer)?; match bson_val { bson::Bson::DateTime(dt) => Ok(dt.into()), bson::Bson::String(s) => s.parse::>().map_err(serde::de::Error::custom), other => Err(serde::de::Error::custom(format!( "expected DateTime or string, got: {other:?}" ))), } } } /// Serialize/deserialize `Option>` as BSON DateTime. pub mod opt_bson_datetime { use super::*; use serde::Serialize as _; pub fn serialize(dt: &Option>, serializer: S) -> Result where S: Serializer, { match dt { Some(dt) => { let bson_dt: bson::DateTime = (*dt).into(); bson_dt.serialize(serializer) } None => serializer.serialize_none(), } } pub fn deserialize<'de, D>(deserializer: D) -> Result>, D::Error> where D: Deserializer<'de>, { let bson_val = Option::::deserialize(deserializer)?; match bson_val { Some(bson::Bson::DateTime(dt)) => Ok(Some(dt.into())), Some(bson::Bson::String(s)) => s .parse::>() .map(Some) .map_err(serde::de::Error::custom), Some(bson::Bson::Null) | None => Ok(None), Some(other) => Err(serde::de::Error::custom(format!( "expected DateTime, string, or null, got: {other:?}" ))), } } }