Skip to main content

rkyv/impls/core/
time.rs

1use core::time::Duration;
2
3use rancor::Fallible;
4
5use crate::{time::ArchivedDuration, Archive, Deserialize, Place, Serialize};
6
7impl Archive for Duration {
8    type Archived = ArchivedDuration;
9    type Resolver = ();
10
11    #[inline]
12    fn resolve(&self, _: Self::Resolver, out: Place<Self::Archived>) {
13        unsafe {
14            ArchivedDuration::emplace(
15                self.as_secs(),
16                self.subsec_nanos(),
17                out.ptr(),
18            );
19        }
20    }
21}
22
23impl<S: Fallible + ?Sized> Serialize<S> for Duration {
24    fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> {
25        Ok(())
26    }
27}
28
29impl<D: Fallible + ?Sized> Deserialize<Duration, D> for ArchivedDuration {
30    fn deserialize(&self, _: &mut D) -> Result<Duration, D::Error> {
31        Ok(Duration::new(self.as_secs(), self.subsec_nanos()))
32    }
33}
34
35impl PartialEq<Duration> for ArchivedDuration {
36    #[inline]
37    fn eq(&self, other: &Duration) -> bool {
38        self.as_nanos() == other.as_nanos() && self.as_secs() == other.as_secs()
39    }
40}
41
42impl PartialEq<ArchivedDuration> for Duration {
43    #[inline]
44    fn eq(&self, other: &ArchivedDuration) -> bool {
45        other.eq(self)
46    }
47}
48
49impl From<ArchivedDuration> for Duration {
50    #[inline]
51    fn from(duration: ArchivedDuration) -> Self {
52        Self::new(duration.as_secs(), duration.subsec_nanos())
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use core::time::Duration;
59
60    use crate::api::test::roundtrip;
61
62    #[test]
63    fn roundtrip_duration() {
64        roundtrip(&Duration::new(1234, 5678));
65    }
66
67    // Synthetic buffer is for 32-bit little-endian
68    #[cfg(all(
69        not(feature = "pointer_width_16"),
70        not(feature = "pointer_width_64"),
71        not(feature = "big_endian"),
72        feature = "bytecheck",
73    ))]
74    #[test]
75    fn invalid_duration() {
76        use rancor::Failure;
77
78        use crate::{api::low::from_bytes, util::Align};
79
80        // This buffer is invalid because `nanos` is equal to 1 billion (nanos
81        // may not be one billion or more)
82        let data = Align([
83            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // secs
84            0x00, 0xca, 0x9a, 0x3b, // nanos
85            0x00, 0x00, 0x00, 0x00, // padding
86        ]);
87        from_bytes::<Duration, Failure>(&*data).unwrap_err();
88    }
89}