use crate::DeserializeRevisioned;
use crate::SerializeRevisioned;
use super::super::Error;
use super::super::Revisioned;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
impl SerializeRevisioned for SystemTime {
#[inline]
fn serialize_revisioned<W: std::io::Write>(&self, writer: &mut W) -> Result<(), Error> {
let duration =
self.duration_since(UNIX_EPOCH).map_err(|e| Error::Serialize(e.to_string()))?;
duration.as_secs().serialize_revisioned(writer)?;
duration.subsec_nanos().serialize_revisioned(writer)
}
}
impl DeserializeRevisioned for SystemTime {
#[inline]
fn deserialize_revisioned<R: std::io::Read>(reader: &mut R) -> Result<Self, Error> {
let secs = u64::deserialize_revisioned(reader)?;
let nanos = u32::deserialize_revisioned(reader)?;
Ok(UNIX_EPOCH + Duration::new(secs, nanos))
}
}
impl Revisioned for SystemTime {
#[inline]
fn revision() -> u16 {
1
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Error;
#[test]
fn test_system_time_now() {
let val = SystemTime::now();
let mut mem: Vec<u8> = vec![];
val.serialize_revisioned(&mut mem).unwrap();
let out =
<SystemTime as DeserializeRevisioned>::deserialize_revisioned(&mut mem.as_slice())
.unwrap();
assert_eq!(val, out);
}
#[test]
fn test_system_time_epoch() {
let val = UNIX_EPOCH;
let mut mem: Vec<u8> = vec![];
val.serialize_revisioned(&mut mem).unwrap();
let out =
<SystemTime as DeserializeRevisioned>::deserialize_revisioned(&mut mem.as_slice())
.unwrap();
assert_eq!(val, out);
}
#[test]
fn test_system_time_future() {
let val = UNIX_EPOCH + Duration::new(u32::MAX as u64, 999_999_999);
let mut mem: Vec<u8> = vec![];
val.serialize_revisioned(&mut mem).unwrap();
let out =
<SystemTime as DeserializeRevisioned>::deserialize_revisioned(&mut mem.as_slice())
.unwrap();
assert_eq!(val, out);
}
#[test]
fn test_system_time_pre_epoch() {
let val = UNIX_EPOCH - Duration::new(1, 0);
let mut mem: Vec<u8> = vec![];
let result = val.serialize_revisioned(&mut mem);
assert!(result.is_err());
assert!(matches!(result.unwrap_err(), Error::Serialize(_)));
}
#[test]
fn test_system_time_one_sec_after_epoch() {
let val = UNIX_EPOCH + Duration::new(1, 0);
let mut mem: Vec<u8> = vec![];
val.serialize_revisioned(&mut mem).unwrap();
let out =
<SystemTime as DeserializeRevisioned>::deserialize_revisioned(&mut mem.as_slice())
.unwrap();
assert_eq!(val, out);
}
#[test]
fn test_system_time_max_nanos() {
let val = UNIX_EPOCH + Duration::new(0, 999_999_999);
let mut mem: Vec<u8> = vec![];
val.serialize_revisioned(&mut mem).unwrap();
let out =
<SystemTime as DeserializeRevisioned>::deserialize_revisioned(&mut mem.as_slice())
.unwrap();
assert_eq!(val, out);
}
#[test]
fn test_system_time_large_secs() {
let large_secs = i64::MAX as u64;
let val = UNIX_EPOCH + Duration::new(large_secs, 999_999_999);
let mut mem: Vec<u8> = vec![];
val.serialize_revisioned(&mut mem).unwrap();
let out =
<SystemTime as DeserializeRevisioned>::deserialize_revisioned(&mut mem.as_slice())
.unwrap();
assert_eq!(val, out);
}
#[test]
fn test_system_time_revision() {
assert_eq!(<SystemTime as Revisioned>::revision(), 1);
}
#[test]
fn test_system_time_serialized_bytes() {
let val = UNIX_EPOCH + Duration::new(12345, 678);
let mut time_bytes: Vec<u8> = vec![];
val.serialize_revisioned(&mut time_bytes).unwrap();
let duration = val.duration_since(UNIX_EPOCH).unwrap();
let mut expected_bytes: Vec<u8> = vec![];
duration.as_secs().serialize_revisioned(&mut expected_bytes).unwrap();
duration.subsec_nanos().serialize_revisioned(&mut expected_bytes).unwrap();
assert_eq!(time_bytes, expected_bytes);
}
#[test]
fn test_system_time_truncated_data() {
let val = UNIX_EPOCH + Duration::new(12345, 678);
let mut mem: Vec<u8> = vec![];
val.serialize_revisioned(&mut mem).unwrap();
let mut truncated = &mem[..2];
let result = <SystemTime as DeserializeRevisioned>::deserialize_revisioned(&mut truncated);
assert!(result.is_err());
}
#[test]
fn test_system_time_empty_reader() {
let mut empty: &[u8] = &[];
let result = <SystemTime as DeserializeRevisioned>::deserialize_revisioned(&mut empty);
assert!(result.is_err());
}
#[test]
fn test_system_time_known_timestamp() {
let secs_2000_01_01 = 946684800u64;
let val = UNIX_EPOCH + Duration::new(secs_2000_01_01, 0);
let mut mem: Vec<u8> = vec![];
val.serialize_revisioned(&mut mem).unwrap();
let out =
<SystemTime as DeserializeRevisioned>::deserialize_revisioned(&mut mem.as_slice())
.unwrap();
assert_eq!(val, out);
let duration = out.duration_since(UNIX_EPOCH).unwrap();
assert_eq!(duration.as_secs(), secs_2000_01_01);
assert_eq!(duration.subsec_nanos(), 0);
}
#[test]
fn test_system_time_with_nanos() {
let val = UNIX_EPOCH + Duration::new(1000, 123_456_789);
let mut mem: Vec<u8> = vec![];
val.serialize_revisioned(&mut mem).unwrap();
let out =
<SystemTime as DeserializeRevisioned>::deserialize_revisioned(&mut mem.as_slice())
.unwrap();
assert_eq!(val, out);
let duration = out.duration_since(UNIX_EPOCH).unwrap();
assert_eq!(duration.as_secs(), 1000);
assert_eq!(duration.subsec_nanos(), 123_456_789);
}
#[test]
fn test_system_time_one_nanosecond() {
let val = UNIX_EPOCH + Duration::new(0, 1);
let mut mem: Vec<u8> = vec![];
val.serialize_revisioned(&mut mem).unwrap();
let out =
<SystemTime as DeserializeRevisioned>::deserialize_revisioned(&mut mem.as_slice())
.unwrap();
assert_eq!(val, out);
}
#[test]
fn test_system_time_epoch_bytes() {
let val = UNIX_EPOCH;
let mut mem: Vec<u8> = vec![];
val.serialize_revisioned(&mut mem).unwrap();
let mut expected: Vec<u8> = vec![];
0u64.serialize_revisioned(&mut expected).unwrap();
0u32.serialize_revisioned(&mut expected).unwrap();
assert_eq!(mem, expected);
}
#[test]
fn test_system_time_partial_secs_truncated() {
let val = UNIX_EPOCH + Duration::new(12345, 678);
let mut mem: Vec<u8> = vec![];
val.serialize_revisioned(&mut mem).unwrap();
let mut secs_only = &mem[..mem.len() - 1];
let result = <SystemTime as DeserializeRevisioned>::deserialize_revisioned(&mut secs_only);
assert!(result.is_err());
}
}