72 lines
2.1 KiB
Rust
72 lines
2.1 KiB
Rust
//! De-/serialization functions for `std::time::SystemTime` objects represented as milliseconds
|
|
//! since the UNIX epoch. Delegates to `js_int::UInt` to ensure integer size is within bounds.
|
|
|
|
use std::{
|
|
convert::TryFrom,
|
|
time::{Duration, SystemTime, UNIX_EPOCH},
|
|
};
|
|
|
|
use js_int::UInt;
|
|
use serde::{
|
|
de::{Deserialize, Deserializer},
|
|
ser::{Error, Serialize, Serializer},
|
|
};
|
|
|
|
/// Serialize a SystemTime.
|
|
///
|
|
/// Will fail if integer is greater than the maximum integer that can be unambiguously represented
|
|
/// by an f64.
|
|
pub fn serialize<S>(time: &SystemTime, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: Serializer,
|
|
{
|
|
// If this unwrap fails, the system this is executed is completely broken.
|
|
let time_since_epoch = time.duration_since(UNIX_EPOCH).unwrap();
|
|
match UInt::try_from(time_since_epoch.as_millis()) {
|
|
Ok(uint) => uint.serialize(serializer),
|
|
Err(err) => Err(S::Error::custom(err)),
|
|
}
|
|
}
|
|
|
|
/// Deserializes a SystemTime.
|
|
///
|
|
/// Will fail if integer is greater than the maximum integer that can be unambiguously represented
|
|
/// by an f64.
|
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<SystemTime, D::Error>
|
|
where
|
|
D: Deserializer<'de>,
|
|
{
|
|
let millis = UInt::deserialize(deserializer)?;
|
|
Ok(UNIX_EPOCH + Duration::from_millis(millis.into()))
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
use serde_json::json;
|
|
|
|
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
|
struct SystemTimeTest {
|
|
#[serde(with = "super")]
|
|
timestamp: SystemTime,
|
|
}
|
|
|
|
#[test]
|
|
fn test_deserialize() {
|
|
let json = json!({ "timestamp": 3000 });
|
|
|
|
assert_eq!(
|
|
serde_json::from_value::<SystemTimeTest>(json).unwrap(),
|
|
SystemTimeTest { timestamp: UNIX_EPOCH + Duration::from_millis(3000) },
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_serialize() {
|
|
let request = SystemTimeTest { timestamp: UNIX_EPOCH + Duration::new(2, 0) };
|
|
assert_eq!(serde_json::to_value(&request).unwrap(), json!({ "timestamp": 2000 }));
|
|
}
|
|
}
|