diff --git a/src/serde_helpers.rs b/src/serde_helpers.rs index b015c3ea..e836d1c0 100644 --- a/src/serde_helpers.rs +++ b/src/serde_helpers.rs @@ -23,6 +23,11 @@ pub use hex_string_as_object_id::{ serialize as serialize_hex_string_as_object_id, }; #[doc(inline)] +pub use i64_as_datetime::{ + deserialize as deserialize_i64_from_datetime, + serialize as serialize_i64_as_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, @@ -412,6 +417,40 @@ pub mod hex_string_as_object_id { } } +/// Contains functions to `serialize` a `i64` integer as `DateTime` and `deserialize` +/// a `i64` integer from `DateTime` +/// +/// ### The i64 should represent seconds `(DateTime::timestamp_millis(..))`. +/// +/// ```rust +/// # use serde::{Serialize, Deserialize}; +/// # use bson::serde_helpers::i64_as_datetime; +/// #[derive(Serialize, Deserialize)] +/// struct Item { +/// #[serde(with = "i64_as_datetime")] +/// pub now: i64, +/// } +/// ``` +pub mod i64_as_datetime { + use crate::DateTime; + use serde::{Deserialize, Deserializer, Serialize, Serializer}; + + /// Deserializes a i64 integer from a DateTime. + pub fn deserialize<'de, D>(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let date: DateTime = DateTime::deserialize(deserializer)?; + Ok(date.timestamp_millis()) + } + + /// Serializes a i64 integer as a DateTime. + pub fn serialize(val: &i64, serializer: S) -> Result { + let date_time = DateTime::from_millis(*val); + date_time.serialize(serializer) + } +} + #[allow(unused_macros)] macro_rules! as_binary_mod { ($feat:meta, $uu:path) => { diff --git a/src/tests/serde.rs b/src/tests/serde.rs index 362587a8..0718c2e9 100644 --- a/src/tests/serde.rs +++ b/src/tests/serde.rs @@ -10,6 +10,7 @@ use crate::{ serde_helpers::{ bson_datetime_as_rfc3339_string, hex_string_as_object_id, + i64_as_datetime, rfc3339_string_as_bson_datetime, serialize_object_id_as_hex_string, timestamp_as_u32, @@ -886,6 +887,26 @@ fn test_oid_helpers() { assert_eq!(a.oid, oid.to_string()); } +#[test] +fn test_i64_as_datetime() { + let _guard = LOCK.run_concurrently(); + + #[derive(Serialize, Deserialize)] + struct A { + #[serde(with = "i64_as_datetime")] + now: i64, + } + + let now = DateTime::now(); + let a = A { + now: now.timestamp_millis(), + }; + let doc = to_document(&a).unwrap(); + assert_eq!(doc.get_datetime("now").unwrap(), &now); + let a: A = from_document(doc).unwrap(); + assert_eq!(a.now, now.timestamp_millis()); +} + #[test] #[cfg(feature = "uuid-0_8")] fn test_uuid_0_8_helpers() {