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 i64_as_bson_datetime::{
deserialize as deserialize_i64_from_bson_datetime,
serialize as serialize_i64_as_bson_datetime,
};
#[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,
};
#[cfg(feature = "time-0_3")]
#[doc(inline)]
pub use time_0_3_offsetdatetime_as_bson_datetime::{
deserialize as deserialize_time_0_3_offsetdatetime_from_bson_datetime,
serialize as serialize_time_0_3_offsetdatetime_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-1")]
#[doc(inline)]
pub use uuid_1_as_binary::{
deserialize as deserialize_uuid_1_from_binary,
serialize as serialize_uuid_1_as_binary,
};
#[cfg(feature = "uuid-1")]
#[doc(inline)]
pub use uuid_1_as_c_sharp_legacy_binary::{
deserialize as deserialize_uuid_1_from_c_sharp_legacy_binary,
serialize as serialize_uuid_1_as_c_sharp_legacy_binary,
};
#[cfg(feature = "uuid-1")]
#[doc(inline)]
pub use uuid_1_as_java_legacy_binary::{
deserialize as deserialize_uuid_1_from_java_legacy_binary,
serialize as serialize_uuid_1_as_java_legacy_binary,
};
#[cfg(feature = "uuid-1")]
#[doc(inline)]
pub use uuid_1_as_python_legacy_binary::{
deserialize as deserialize_uuid_1_from_python_legacy_binary,
serialize as serialize_uuid_1_as_python_legacy_binary,
};
#[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 = "time-0_3")]
#[cfg_attr(docsrs, doc(cfg(feature = "time-0_3")))]
pub mod time_0_3_offsetdatetime_as_bson_datetime {
use crate::DateTime;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::result::Result;
#[cfg_attr(docsrs, doc(cfg(feature = "time-0_3")))]
pub fn deserialize<'de, D>(deserializer: D) -> Result<time::OffsetDateTime, D::Error>
where
D: Deserializer<'de>,
{
let datetime = DateTime::deserialize(deserializer)?;
Ok(datetime.to_time_0_3())
}
#[cfg_attr(docsrs, doc(cfg(feature = "time-0_3")))]
pub fn serialize<S: Serializer>(
val: &time::OffsetDateTime,
serializer: S,
) -> Result<S::Ok, S::Error> {
let datetime = DateTime::from_time_0_3(val.to_owned());
datetime.serialize(serializer)
}
}
#[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::{de, 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)?;
date.try_to_rfc3339_string()
.map_err(|e| de::Error::custom(format!("cannot format {} as RFC 3339: {}", date, e)))
}
pub fn serialize<S: Serializer>(val: &str, serializer: S) -> Result<S::Ok, S::Error> {
let date = crate::DateTime::parse_rfc3339_str(val)
.map_err(|_| ser::Error::custom(format!("cannot convert {} to DateTime", val)))?;
Bson::DateTime(date).serialize(serializer)
}
}
pub mod bson_datetime_as_rfc3339_string {
use crate::DateTime;
use serde::{de, ser, 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 = crate::DateTime::parse_rfc3339_str(&iso).map_err(|_| {
de::Error::custom(format!("cannot parse RFC 3339 datetime from \"{}\"", iso))
})?;
Ok(date)
}
pub fn serialize<S: Serializer>(val: &DateTime, serializer: S) -> Result<S::Ok, S::Error> {
let formatted = val
.try_to_rfc3339_string()
.map_err(|e| ser::Error::custom(format!("cannot format {} as RFC 3339: {}", val, e)))?;
serializer.serialize_str(&formatted)
}
}
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
))),
}
}
}
pub mod i64_as_bson_datetime {
use crate::DateTime;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
pub fn deserialize<'de, D>(deserializer: D) -> Result<i64, D::Error>
where
D: Deserializer<'de>,
{
let date: DateTime = DateTime::deserialize(deserializer)?;
Ok(date.timestamp_millis())
}
pub fn serialize<S: Serializer>(val: &i64, serializer: S) -> Result<S::Ok, S::Error> {
let date_time = DateTime::from_millis(*val);
date_time.serialize(serializer)
}
}
#[allow(unused_macros)]
macro_rules! as_binary_mod {
($feat:meta, $uu:path) => {
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::result::Result;
use $uu;
#[cfg_attr(docsrs, doc($feat))]
pub fn serialize<S: Serializer>(val: &Uuid, serializer: S) -> Result<S::Ok, S::Error> {
crate::uuid::Uuid::from(*val).serialize(serializer)
}
#[cfg_attr(docsrs, doc($feat))]
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_binary {
as_binary_mod!(cfg(feature = "uuid-0_8"), uuid_0_8::Uuid);
}
#[cfg(feature = "uuid-1")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-1")))]
pub mod uuid_1_as_binary {
as_binary_mod!(cfg(feature = "uuid-1"), uuid::Uuid);
}
#[allow(unused_macros)]
macro_rules! as_legacy_binary_mod {
($feat:meta, $uu:path, $rep:path) => {
use crate::{uuid::UuidRepresentation, Binary};
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use std::result::Result;
use $uu;
#[cfg_attr(docsrs, doc($feat))]
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(*val), $rep);
binary.serialize(serializer)
}
#[cfg_attr(docsrs, doc($feat))]
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($rep)
.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_java_legacy_binary {
as_legacy_binary_mod!(
cfg(feature = "uuid-0_8"),
uuid_0_8::Uuid,
UuidRepresentation::JavaLegacy
);
}
#[cfg(feature = "uuid-1")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-1")))]
pub mod uuid_1_as_java_legacy_binary {
as_legacy_binary_mod!(
cfg(feature = "uuid-1"),
uuid::Uuid,
UuidRepresentation::JavaLegacy
);
}
#[cfg(feature = "uuid-0_8")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
pub mod uuid_as_python_legacy_binary {
as_legacy_binary_mod!(
cfg(feature = "uuid-0_8"),
uuid_0_8::Uuid,
UuidRepresentation::PythonLegacy
);
}
#[cfg(feature = "uuid-1")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-1")))]
pub mod uuid_1_as_python_legacy_binary {
as_legacy_binary_mod!(
cfg(feature = "uuid-1"),
uuid::Uuid,
UuidRepresentation::PythonLegacy
);
}
#[cfg(feature = "uuid-0_8")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-0_8")))]
pub mod uuid_as_c_sharp_legacy_binary {
as_legacy_binary_mod!(
cfg(feature = "uuid-0_8"),
uuid_0_8::Uuid,
UuidRepresentation::CSharpLegacy
);
}
#[cfg(feature = "uuid-1")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid-1")))]
pub mod uuid_1_as_c_sharp_legacy_binary {
as_legacy_binary_mod!(
cfg(feature = "uuid-1"),
uuid::Uuid,
UuidRepresentation::CSharpLegacy
);
}
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 })
}
}