LCOV - code coverage report
Current view: top level - libs/utils/src - serde_system_time.rs (source / functions) Coverage Total Hit
Test: 09e7485004805bd42b53a0c369170b3228136512.info Lines: 96.9 % 32 31
Test Date: 2024-11-21 18:36:18 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            1 : #[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            2 : fn ser_rfc3339_millis<S: serde::ser::Serializer>(
      14            2 :     ts: &std::time::SystemTime,
      15            2 :     serializer: S,
      16            2 : ) -> Result<S::Ok, S::Error> {
      17            2 :     serializer.collect_str(&humantime::format_rfc3339_millis(*ts))
      18            2 : }
      19              : 
      20            1 : fn deser_rfc3339_millis<'de, D>(deserializer: D) -> Result<std::time::SystemTime, D::Error>
      21            1 : where
      22            1 :     D: serde::de::Deserializer<'de>,
      23            1 : {
      24            1 :     let s: String = serde::de::Deserialize::deserialize(deserializer)?;
      25            1 :     humantime::parse_rfc3339(&s).map_err(serde::de::Error::custom)
      26            1 : }
      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            1 :     fn to_millisecond_precision(time: SystemTime) -> SystemTime {
      34            1 :         match time.0.duration_since(std::time::SystemTime::UNIX_EPOCH) {
      35            1 :             Ok(duration) => {
      36            1 :                 let total_millis = duration.as_secs() * 1_000 + u64::from(duration.subsec_millis());
      37            1 :                 SystemTime(
      38            1 :                     std::time::SystemTime::UNIX_EPOCH
      39            1 :                         + std::time::Duration::from_millis(total_millis),
      40            1 :                 )
      41              :             }
      42            0 :             Err(_) => time,
      43              :         }
      44            1 :     }
      45              : 
      46              :     #[test]
      47            1 :     fn test_serialize_deserialize() {
      48            1 :         let input = SystemTime(std::time::SystemTime::now());
      49            1 :         let expected_serialized = format!("\"{}\"", humantime::format_rfc3339_millis(input.0));
      50            1 :         let serialized = serde_json::to_string(&input).unwrap();
      51            1 :         assert_eq!(expected_serialized, serialized);
      52            1 :         let deserialized: SystemTime = serde_json::from_str(&expected_serialized).unwrap();
      53            1 :         assert_eq!(to_millisecond_precision(input), deserialized);
      54            1 :     }
      55              : }
        

Generated by: LCOV version 2.1-beta