messagepack_core/
timestamp.rs

1//! MessagePack timestamp extension values.
2
3pub(crate) const TIMESTAMP_EXTENSION_TYPE: i8 = -1;
4
5/// Represents timestamp 32 extension type.
6/// This stores 32bit unsigned seconds
7#[derive(Clone, Copy, Debug)]
8pub struct Timestamp32 {
9    secs: u32,
10}
11
12impl Timestamp32 {
13    /// Create a 32‑bit seconds timestamp.
14    pub fn new(seconds: u32) -> Self {
15        Self { secs: seconds }
16    }
17
18    /// Get seconds since the UNIX epoch.
19    pub fn seconds(&self) -> u32 {
20        self.secs
21    }
22
23    pub(crate) fn to_buf(self) -> [u8; 4] {
24        self.secs.to_be_bytes()
25    }
26
27    pub(crate) fn from_buf(buf: [u8; 4]) -> Self {
28        Self {
29            secs: u32::from_be_bytes(buf),
30        }
31    }
32}
33
34/// Represents timestamp 64 extension type.
35/// This stores 34bit unsigned seconds and 30bit nanoseconds
36#[derive(Clone, Copy, Debug)]
37pub struct Timestamp64 {
38    data: [u8; 8],
39}
40
41/// `seconds` or `nanos` cannot be represented
42#[derive(Clone, Debug)]
43pub struct Timestamp64Error {
44    /// Requested seconds that exceeded the 34‑bit range.
45    pub seconds: u64,
46    /// Requested nanoseconds that exceeded the 30‑bit range.
47    pub nanos: u32,
48}
49
50impl Timestamp64 {
51    /// Create a 64‑bit timestamp storing 34‑bit seconds and 30‑bit nanoseconds.
52    pub fn new(seconds: u64, nanos: u32) -> Result<Self, Timestamp64Error> {
53        const SECONDS_MAX_LIMIT: u64 = 1 << 34;
54
55        if seconds >= SECONDS_MAX_LIMIT {
56            return Err(Timestamp64Error { seconds, nanos });
57        }
58
59        const NANOS_MAX_LIMIT: u32 = 1 << 30;
60        if nanos >= NANOS_MAX_LIMIT {
61            return Err(Timestamp64Error { seconds, nanos });
62        }
63
64        let mut buf = [0u8; 8];
65        buf[..].copy_from_slice(&seconds.to_be_bytes());
66
67        let nano = (nanos << 2).to_be_bytes();
68        buf[..3].copy_from_slice(&nano[..3]);
69        buf[3] |= nano[3];
70
71        Ok(Self::from_buf(buf))
72    }
73
74    /// Get the nanoseconds component.
75    pub fn nanos(&self) -> u32 {
76        let mut buf = [0u8; 4];
77        buf.copy_from_slice(&self.data[..4]);
78        let nanosec = u32::from_be_bytes(buf);
79        nanosec >> 2
80    }
81
82    /// Get the seconds component.
83    pub fn seconds(&self) -> u64 {
84        // 34bit mask
85        const MASK: u64 = (1 << 34) - 1;
86        let mut buf = [0u8; 8];
87        buf.copy_from_slice(&self.data[..]);
88        let seconds = u64::from_be_bytes(buf);
89
90        seconds & MASK
91    }
92
93    pub(crate) fn to_buf(self) -> [u8; 8] {
94        self.data
95    }
96
97    pub(crate) fn from_buf(buf: [u8; 8]) -> Self {
98        Self { data: buf }
99    }
100}
101
102/// Represents timestamp 96 extension type.
103/// This stores 64bit signed seconds and 32bit nanoseconds
104#[derive(Clone, Copy, Debug)]
105pub struct Timestamp96 {
106    nanos: u32,
107    secs: i64,
108}
109
110impl Timestamp96 {
111    /// Create a 96‑bit timestamp storing signed seconds and nanoseconds.
112    pub fn new(seconds: i64, nanoseconds: u32) -> Self {
113        Self {
114            nanos: nanoseconds,
115            secs: seconds,
116        }
117    }
118
119    /// Get the nanoseconds component.
120    pub fn nanos(&self) -> u32 {
121        self.nanos
122    }
123
124    /// Get the seconds component.
125    pub fn seconds(&self) -> i64 {
126        self.secs
127    }
128
129    pub(crate) fn to_buf(self) -> [u8; 12] {
130        let mut buf = [0u8; 12];
131        buf[..4].copy_from_slice(&self.nanos.to_be_bytes());
132        buf[4..].copy_from_slice(&self.secs.to_be_bytes());
133
134        buf
135    }
136
137    pub(crate) fn from_buf(buf: [u8; 12]) -> Self {
138        let mut nano = [0u8; 4];
139        nano.copy_from_slice(&buf[..4]);
140
141        let mut second = [0u8; 8];
142        second.copy_from_slice(&buf[4..]);
143
144        Self {
145            nanos: u32::from_be_bytes(nano),
146            secs: i64::from_be_bytes(second),
147        }
148    }
149}