LCOV - code coverage report
Current view: top level - libs/utils/src - serde_system_time.rs (source / functions) Coverage Total Hit
Test: 792183ae0ef4f1f8b22e9ac7e8748740ab73f873.info Lines: 96.9 % 32 31
Test Date: 2024-06-26 01:04:33 Functions: 38.5 % 13 5

            Line data    Source code
       1              : //! A `serde::{Deserialize,Serialize}` type for SystemTime with RFC3339 format and millisecond precision.
       2              : 
       3            2 : #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
       4              : #[serde(transparent)]
       5              : pub struct SystemTime(
       6              :     #[serde(
       7              :         deserialize_with = "deser_rfc3339_millis",
       8              :         serialize_with = "ser_rfc3339_millis"
       9              :     )]
      10              :     pub std::time::SystemTime,
      11              : );
      12              : 
      13            4 : fn ser_rfc3339_millis<S: serde::ser::Serializer>(
      14            4 :     ts: &std::time::SystemTime,
      15            4 :     serializer: S,
      16            4 : ) -> Result<S::Ok, S::Error> {
      17            4 :     serializer.collect_str(&humantime::format_rfc3339_millis(*ts))
      18            4 : }
      19              : 
      20            2 : fn deser_rfc3339_millis<'de, D>(deserializer: D) -> Result<std::time::SystemTime, D::Error>
      21            2 : where
      22            2 :     D: serde::de::Deserializer<'de>,
      23            2 : {
      24            2 :     let s: String = serde::de::Deserialize::deserialize(deserializer)?;
      25            2 :     humantime::parse_rfc3339(&s).map_err(serde::de::Error::custom)
      26            2 : }
      27              : 
      28              : #[cfg(test)]
      29              : mod tests {
      30              :     use super::*;
      31              : 
      32              :     /// Helper function to make a SystemTime have millisecond precision by truncating additional nanoseconds.
      33            2 :     fn to_millisecond_precision(time: SystemTime) -> SystemTime {
      34            2 :         match time.0.duration_since(std::time::SystemTime::UNIX_EPOCH) {
      35            2 :             Ok(duration) => {
      36            2 :                 let total_millis = duration.as_secs() * 1_000 + u64::from(duration.subsec_millis());
      37            2 :                 SystemTime(
      38            2 :                     std::time::SystemTime::UNIX_EPOCH
      39            2 :                         + std::time::Duration::from_millis(total_millis),
      40            2 :                 )
      41              :             }
      42            0 :             Err(_) => time,
      43              :         }
      44            2 :     }
      45              : 
      46              :     #[test]
      47            2 :     fn test_serialize_deserialize() {
      48            2 :         let input = SystemTime(std::time::SystemTime::now());
      49            2 :         let expected_serialized = format!("\"{}\"", humantime::format_rfc3339_millis(input.0));
      50            2 :         let serialized = serde_json::to_string(&input).unwrap();
      51            2 :         assert_eq!(expected_serialized, serialized);
      52            2 :         let deserialized: SystemTime = serde_json::from_str(&expected_serialized).unwrap();
      53            2 :         assert_eq!(to_millisecond_precision(input), deserialized);
      54            2 :     }
      55              : }
        

Generated by: LCOV version 2.1-beta