use std::{convert::TryFrom, result::Result};
use serde::{ser, Serialize, Serializer};
use crate::oid::ObjectId;
#[doc(inline)]
pub use bson_datetime_as_rfc3339_string::{
deserialize as deserialize_bson_datetime_from_rfc3339_string,
serialize as serialize_bson_datetime_as_rfc3339_string,
};
#[cfg(feature = "chrono-0_4")]
#[doc(inline)]
pub use chrono_datetime_as_bson_datetime::{
deserialize as deserialize_chrono_datetime_from_bson_datetime,
serialize as serialize_chrono_datetime_as_bson_datetime,
};
#[doc(inline)]
pub use hex_string_as_object_id::{
deserialize as deserialize_hex_string_from_object_id,
serialize as serialize_hex_string_as_object_id,
};
#[doc(inline)]
pub use rfc3339_string_as_bson_datetime::{
deserialize as deserialize_rfc3339_string_from_bson_datetime,
serialize as serialize_rfc3339_string_as_bson_datetime,
};
#[doc(inline)]
pub use timestamp_as_u32::{
deserialize as deserialize_timestamp_from_u32,
serialize as serialize_timestamp_as_u32,
};
#[doc(inline)]
pub use u32_as_f64::{deserialize as deserialize_u32_from_f64, serialize as serialize_u32_as_f64};
#[doc(inline)]
pub use u32_as_timestamp::{
deserialize as deserialize_u32_from_timestamp,
serialize as serialize_u32_as_timestamp,
};
#[doc(inline)]
pub use u64_as_f64::{deserialize as deserialize_u64_from_f64, serialize as serialize_u64_as_f64};
#[cfg(feature = "uuid-0_8")]
#[doc(inline)]
pub use uuid_as_binary::{
deserialize as deserialize_uuid_from_binary,
serialize as serialize_uuid_as_binary,
};
#[cfg(feature = "uuid-0_8")]
#[doc(inline)]
pub use uuid_as_c_sharp_legacy_binary::{
deserialize as deserialize_uuid_from_c_sharp_legacy_binary,
serialize as serialize_uuid_as_c_sharp_legacy_binary,
};
#[cfg(feature = "uuid-0_8")]
#[doc(inline)]
pub use uuid_as_java_legacy_binary::{
deserialize as deserialize_uuid_from_java_legacy_binary,
serialize as serialize_uuid_as_java_legacy_binary,
};
#[cfg(feature = "uuid-0_8")]
#[doc(inline)]
pub use uuid_as_python_legacy_binary::{
deserialize as deserialize_uuid_from_python_legacy_binary,
serialize as serialize_uuid_as_python_legacy_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 fn serialize_object_id_as_hex_string<S: Serializer>(
val: &ObjectId,
serializer: S,
) -> Result<S::Ok, S::Error> {
val.to_hex().serialize(serializer)
}
pub mod u32_as_f64 {
use serde::{de, Deserialize, Deserializer, Serializer};
pub fn deserialize<'de, D>(deserializer: D) -> Result<u32, D::Error>
where
D: Deserializer<'de>,
{
let f = f64::deserialize(deserializer)?;
if (f - f as u32 as f64).abs() <= f64::EPSILON {
Ok(f as u32)
} else {
Err(de::Error::custom(format!(
"cannot convert f64 (BSON double) {} to u32",
f
)))
}
}
pub fn serialize<S: Serializer>(val: &u32, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_f64(*val as f64)
}
}
pub mod u64_as_f64 {
use serde::{de, ser, Deserialize, Deserializer, Serializer};
pub fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
where
D: Deserializer<'de>,
{
let f = f64::deserialize(deserializer)?;
if (f - f as u64 as f64).abs() <= f64::EPSILON {
Ok(f as u64)
} else {
Err(de::Error::custom(format!(
"cannot convert f64 (BSON double) {} to u64",
f
)))
}
}
pub fn serialize<S: Serializer>(val: &u64, serializer: S) -> Result<S::Ok, S::Error> {
if val < &u64::MAX && *val == *val as f64 as u64 {
serializer.serialize_f64(*val as f64)
} else {
Err(ser::Error::custom(format!(
"cannot convert u64 {} to f64 (BSON double)",
val
)))
}
}
}
#[cfg(feature = "chrono-0_4")]
#[cfg_attr(docsrs, doc(cfg(feature = "chrono-0_4")))]
pub mod chrono_datetime_as_bson_datetime {
use crate::DateTime;
use chrono::Utc;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::result::Result;
#[cfg_attr(docsrs, doc(cfg(feature = "chrono-0_4")))]
pub fn deserialize<'de, D>(deserializer: D) -> Result<chrono::DateTime<Utc>, D::Error>
where
D: Deserializer<'de>,
{
let datetime = DateTime::deserialize(deserializer)?;
Ok(datetime.to_chrono())
}
#[cfg_attr(docsrs, doc(cfg(feature = "chrono-0_4")))]
pub fn serialize<S: Serializer>(
val: &chrono::DateTime<Utc>,
serializer: S,
) -> Result<S::Ok, S::Error> {
let datetime = DateTime::from_chrono(val.to_owned());
datetime.serialize(serializer)
}
}
pub mod rfc3339_string_as_bson_datetime {
use crate::{Bson, DateTime};
use serde::{ser, Deserialize, Deserializer, Serialize, Serializer};
use std::result::Result;
pub fn deserialize<'de, D>(deserializer: D) -> Result<String, D::Error>
where
D: Deserializer<'de>,
{
let date = DateTime::deserialize(deserializer)?;
Ok(date.to_rfc3339_string())
}
pub fn serialize<S: Serializer>(val: &str, serializer: S) -> Result<S::Ok, S::Error> {
let date =
chrono::DateTime::<chrono::FixedOffset>::parse_from_rfc3339(val).map_err(|_| {
ser::Error::custom(format!("cannot convert {} to chrono::DateTime", val))
})?;
Bson::DateTime(crate::DateTime::from_chrono(date)).serialize(serializer)
}
}
pub mod bson_datetime_as_rfc3339_string {
use crate::DateTime;
use serde::{de, Deserialize, Deserializer, Serializer};
use std::result::Result;
pub fn deserialize<'de, D>(deserializer: D) -> Result<DateTime, D::Error>
where
D: Deserializer<'de>,
{
let iso = String::deserialize(deserializer)?;
let date =
chrono::DateTime::<chrono::FixedOffset>::parse_from_rfc3339(&iso).map_err(|_| {
de::Error::custom(format!("cannot parse RFC 3339 datetime from \"{}\"", iso))
})?;
Ok(DateTime::from_chrono(date))
}
pub fn serialize<S: Serializer>(val: &DateTime, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&val.to_rfc3339_string())
}
}
pub mod hex_string_as_object_id {
use crate::oid::ObjectId;
use serde::{ser, Deserialize, Deserializer, Serialize, Serializer};
pub fn deserialize<'de, D>(deserializer: D) -> Result<String, D::Error>
where
D: Deserializer<'de>,
{
let object_id = ObjectId::deserialize(deserializer)?;
Ok(object_id.to_hex())
}
pub fn serialize<S: Serializer>(val: &str, serializer: S) -> Result<S::Ok, S::Error> {
match ObjectId::parse_str(val) {
Ok(oid) => oid.serialize(serializer),
Err(_) => Err(ser::Error::custom(format!(
"cannot convert {} to ObjectId",
val
))),
}
}
}
#[cfg(feature = "uuid-0_8")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
pub mod uuid_as_binary {
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::result::Result;
use uuid::Uuid;
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
pub fn serialize<S: Serializer>(val: &Uuid, serializer: S) -> Result<S::Ok, S::Error> {
crate::uuid::Uuid::from_external_uuid(*val).serialize(serializer)
}
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
pub fn deserialize<'de, D>(deserializer: D) -> Result<Uuid, D::Error>
where
D: Deserializer<'de>,
{
let bson_uuid = crate::uuid::Uuid::deserialize(deserializer)?;
Ok(bson_uuid.into())
}
}
#[cfg(feature = "uuid-0_8")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
pub mod uuid_as_java_legacy_binary {
use crate::{uuid::UuidRepresentation, Binary};
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use std::result::Result;
use uuid::Uuid;
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
pub fn serialize<S: Serializer>(val: &Uuid, serializer: S) -> Result<S::Ok, S::Error> {
let binary = Binary::from_uuid_with_representation(
crate::uuid::Uuid::from_external_uuid(*val),
UuidRepresentation::JavaLegacy,
);
binary.serialize(serializer)
}
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
pub fn deserialize<'de, D>(deserializer: D) -> Result<Uuid, D::Error>
where
D: Deserializer<'de>,
{
let binary = Binary::deserialize(deserializer)?;
let uuid = binary
.to_uuid_with_representation(UuidRepresentation::JavaLegacy)
.map_err(de::Error::custom)?;
Ok(uuid.to_uuid_0_8())
}
}
#[cfg(feature = "uuid-0_8")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
pub mod uuid_as_python_legacy_binary {
use crate::{uuid::UuidRepresentation, Binary};
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use std::result::Result;
use uuid::Uuid;
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
pub fn serialize<S: Serializer>(val: &Uuid, serializer: S) -> Result<S::Ok, S::Error> {
let binary = Binary::from_uuid_with_representation(
crate::uuid::Uuid::from_external_uuid(*val),
UuidRepresentation::PythonLegacy,
);
binary.serialize(serializer)
}
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
pub fn deserialize<'de, D>(deserializer: D) -> Result<Uuid, D::Error>
where
D: Deserializer<'de>,
{
let binary = Binary::deserialize(deserializer)?;
let uuid = binary
.to_uuid_with_representation(UuidRepresentation::PythonLegacy)
.map_err(de::Error::custom)?;
Ok(uuid.into())
}
}
#[cfg(feature = "uuid-0_8")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
pub mod uuid_as_c_sharp_legacy_binary {
use crate::{uuid::UuidRepresentation, Binary};
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use std::result::Result;
use uuid::Uuid;
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
pub fn serialize<S: Serializer>(val: &Uuid, serializer: S) -> Result<S::Ok, S::Error> {
let binary = Binary::from_uuid_with_representation(
crate::uuid::Uuid::from_external_uuid(*val),
UuidRepresentation::CSharpLegacy,
);
binary.serialize(serializer)
}
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
pub fn deserialize<'de, D>(deserializer: D) -> Result<Uuid, D::Error>
where
D: Deserializer<'de>,
{
let binary = Binary::deserialize(deserializer)?;
let uuid = binary
.to_uuid_with_representation(UuidRepresentation::CSharpLegacy)
.map_err(de::Error::custom)?;
Ok(uuid.into())
}
}
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 })
}
}