use std::{convert::TryFrom, result::Result};
use serde::{ser, Serialize, Serializer};
use crate::oid::ObjectId;
pub use bson_datetime_as_iso_string::{
deserialize as deserialize_bson_datetime_from_iso_string,
serialize as serialize_bson_datetime_as_iso_string,
};
pub use chrono_datetime_as_bson_datetime::{
deserialize as deserialize_chrono_datetime_from_bson_datetime,
serialize as serialize_chrono_datetime_as_bson_datetime,
};
pub use iso_string_as_bson_datetime::{
deserialize as deserialize_iso_string_from_bson_datetime,
serialize as serialize_iso_string_as_bson_datetime,
};
pub use timestamp_as_u32::{
deserialize as deserialize_timestamp_from_u32,
serialize as serialize_timestamp_as_u32,
};
pub use u32_as_timestamp::{
deserialize as deserialize_u32_from_timestamp,
serialize as serialize_u32_as_timestamp,
};
pub use uuid_as_binary::{
deserialize as deserialize_uuid_from_binary,
serialize as serialize_uuid_as_binary,
};
pub fn serialize_u32_as_i32<S: Serializer>(val: &u32, serializer: S) -> Result<S::Ok, S::Error> {
match i32::try_from(*val) {
Ok(val) => serializer.serialize_i32(val),
Err(_) => Err(ser::Error::custom(format!("cannot convert {} to i32", val))),
}
}
pub fn serialize_u32_as_i64<S: Serializer>(val: &u32, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_i64(*val as i64)
}
pub fn serialize_u64_as_i32<S: Serializer>(val: &u64, serializer: S) -> Result<S::Ok, S::Error> {
match i32::try_from(*val) {
Ok(val) => serializer.serialize_i32(val),
Err(_) => Err(ser::Error::custom(format!("cannot convert {} to i32", val))),
}
}
pub fn serialize_u64_as_i64<S: Serializer>(val: &u64, serializer: S) -> Result<S::Ok, S::Error> {
match i64::try_from(*val) {
Ok(val) => serializer.serialize_i64(val),
Err(_) => Err(ser::Error::custom(format!("cannot convert {} to i64", val))),
}
}
pub mod chrono_datetime_as_bson_datetime {
use crate::DateTime;
use chrono::Utc;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::result::Result;
pub fn deserialize<'de, D>(deserializer: D) -> Result<chrono::DateTime<Utc>, D::Error>
where
D: Deserializer<'de>,
{
let datetime = DateTime::deserialize(deserializer)?;
Ok(datetime.into())
}
pub fn serialize<S: Serializer>(
val: &chrono::DateTime<Utc>,
serializer: S,
) -> Result<S::Ok, S::Error> {
let datetime = DateTime::from(val.to_owned());
datetime.serialize(serializer)
}
}
pub mod iso_string_as_bson_datetime {
use crate::{Bson, DateTime};
use serde::{ser, Deserialize, Deserializer, Serialize, Serializer};
use std::{result::Result, str::FromStr};
pub fn deserialize<'de, D>(deserializer: D) -> Result<String, D::Error>
where
D: Deserializer<'de>,
{
let date = DateTime::deserialize(deserializer)?;
Ok(date.to_string())
}
pub fn serialize<S: Serializer>(val: &str, serializer: S) -> Result<S::Ok, S::Error> {
let date = chrono::DateTime::from_str(val).map_err(|_| {
ser::Error::custom(format!("cannot convert {} to chrono::DateTime", val))
})?;
Bson::DateTime(date).serialize(serializer)
}
}
pub mod bson_datetime_as_iso_string {
use crate::DateTime;
use serde::{de, Deserialize, Deserializer, Serializer};
use std::{result::Result, str::FromStr};
pub fn deserialize<'de, D>(deserializer: D) -> Result<DateTime, D::Error>
where
D: Deserializer<'de>,
{
let iso = String::deserialize(deserializer)?;
let date = chrono::DateTime::from_str(&iso).map_err(|_| {
de::Error::custom(format!("cannot convert {} to chrono::DateTime", iso))
})?;
Ok(DateTime::from(date))
}
pub fn serialize<S: Serializer>(val: &DateTime, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&val.to_string())
}
}
pub fn serialize_hex_string_as_object_id<S: Serializer>(
val: &str,
serializer: S,
) -> Result<S::Ok, S::Error> {
match ObjectId::with_string(val) {
Ok(oid) => oid.serialize(serializer),
Err(_) => Err(ser::Error::custom(format!(
"cannot convert {} to ObjectId",
val
))),
}
}
pub mod uuid_as_binary {
use crate::{spec::BinarySubtype, Binary};
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use std::result::Result;
use uuid::Uuid;
pub fn serialize<S: Serializer>(val: &Uuid, serializer: S) -> Result<S::Ok, S::Error> {
let binary = Binary {
subtype: BinarySubtype::Uuid,
bytes: val.as_bytes().to_vec(),
};
binary.serialize(serializer)
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<Uuid, D::Error>
where
D: Deserializer<'de>,
{
let binary = Binary::deserialize(deserializer)?;
if binary.subtype == BinarySubtype::Uuid {
if binary.bytes.len() == 16 {
let mut bytes = [0u8; 16];
bytes.copy_from_slice(&binary.bytes);
Ok(Uuid::from_bytes(bytes))
} else {
Err(de::Error::custom(
"cannot convert Binary to Uuid: incorrect bytes length",
))
}
} else {
Err(de::Error::custom(
"cannot convert Binary to Uuid: incorrect binary subtype",
))
}
}
}
pub mod u32_as_timestamp {
use crate::{Bson, Timestamp};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::result::Result;
pub fn serialize<S: Serializer>(val: &u32, serializer: S) -> Result<S::Ok, S::Error> {
let timestamp = Bson::Timestamp(Timestamp {
time: *val,
increment: 0,
});
timestamp.serialize(serializer)
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<u32, D::Error>
where
D: Deserializer<'de>,
{
let timestamp = Timestamp::deserialize(deserializer)?;
Ok(timestamp.time)
}
}
pub mod timestamp_as_u32 {
use crate::Timestamp;
use serde::{ser, Deserialize, Deserializer, Serializer};
use std::result::Result;
pub fn serialize<S: Serializer>(val: &Timestamp, serializer: S) -> Result<S::Ok, S::Error> {
if val.increment != 0 {
return Err(ser::Error::custom(
"Cannot convert Timestamp with a non-zero increment to u32",
));
}
serializer.serialize_u32(val.time)
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<Timestamp, D::Error>
where
D: Deserializer<'de>,
{
let time = u32::deserialize(deserializer)?;
Ok(Timestamp { time, increment: 0 })
}
}