use mongodb::bson::oid::ObjectId;
use serde::{Deserialize, Deserializer, Serializer};
pub fn serialize_object_id_as_string<S>(id: &String, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
if let Ok(oid) = ObjectId::parse_str(id) {
serializer.serialize_some(&oid)
} else {
serializer.serialize_some(id)
}
}
pub fn deserialize_object_id_as_string<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
where
D: Deserializer<'de>,
{
let oid: Option<ObjectId> = Option::deserialize(deserializer)?;
Ok(oid.map(|o| o.to_hex()))
}
pub fn deserialize_object_id<'de, D>(deserializer: D) -> Result<String, D::Error>
where
D: Deserializer<'de>,
{
let oid: ObjectId = ObjectId::deserialize(deserializer)?;
Ok(oid.to_hex())
}
pub fn deserialize_datetime<'de, D>(d: D) -> Result<chrono::DateTime<chrono::Utc>, D::Error>
where
D: serde::Deserializer<'de>,
{
use chrono::TimeZone;
use chrono::Utc;
use mongodb::bson::DateTime as BsonDateTime;
let bson_dt = BsonDateTime::deserialize(d)?;
let millis = bson_dt.timestamp_millis();
let date = Utc
.timestamp_millis_opt(millis)
.single()
.ok_or_else(|| serde::de::Error::custom("invalid or ambiguous timestamp"))?;
Ok(date)
}
pub fn deserialize_option_datetime<'de, D>(
d: D,
) -> Result<Option<chrono::DateTime<chrono::Utc>>, D::Error>
where
D: serde::Deserializer<'de>,
{
use chrono::TimeZone;
use mongodb::bson::DateTime as BsonDateTime;
let opt = Option::<BsonDateTime>::deserialize(d)?;
Ok(opt.and_then(|bson_dt| {
chrono::Utc
.timestamp_millis_opt(bson_dt.timestamp_millis())
.single()
}))
}