messagepack_core/timestamp/
decode.rs1use super::{Timestamp32, Timestamp64, Timestamp96};
4use crate::{
5 Format,
6 decode::{DecodeBorrowed, Error as DecodeError},
7 extension::FixedExtension,
8 io::IoRead,
9};
10
11impl<'de> DecodeBorrowed<'de> for Timestamp32 {
12 type Value = Timestamp32;
13
14 fn decode_borrowed_with_format<R>(
15 format: Format,
16 reader: &mut R,
17 ) -> core::result::Result<Self::Value, DecodeError<R::Error>>
18 where
19 R: IoRead<'de>,
20 {
21 match format {
22 Format::FixExt4 => {}
23 _ => return Err(DecodeError::UnexpectedFormat),
24 }
25 let ext = FixedExtension::<4>::decode_borrowed_with_format(format, reader)?;
26 let timestamp = ext.try_into().map_err(|_| DecodeError::InvalidData)?;
27 Ok(timestamp)
28 }
29}
30
31impl<'de> DecodeBorrowed<'de> for Timestamp64 {
32 type Value = Timestamp64;
33
34 fn decode_borrowed_with_format<R>(
35 format: Format,
36 reader: &mut R,
37 ) -> core::result::Result<Self::Value, DecodeError<R::Error>>
38 where
39 R: IoRead<'de>,
40 {
41 match format {
42 Format::FixExt8 => {}
43 _ => return Err(DecodeError::UnexpectedFormat),
44 }
45 let ext = FixedExtension::<8>::decode_borrowed_with_format(format, reader)?;
46 let timestamp = ext.try_into().map_err(|_| DecodeError::InvalidData)?;
47 Ok(timestamp)
48 }
49}
50
51impl<'de> DecodeBorrowed<'de> for Timestamp96 {
52 type Value = Timestamp96;
53
54 fn decode_borrowed_with_format<R>(
55 format: Format,
56 reader: &mut R,
57 ) -> core::result::Result<Self::Value, DecodeError<R::Error>>
58 where
59 R: IoRead<'de>,
60 {
61 match format {
62 Format::Ext8 => {}
63 _ => return Err(DecodeError::UnexpectedFormat),
64 }
65 const TIMESTAMP96_DATA_LENGTH: usize = 12;
66 let ext =
67 FixedExtension::<TIMESTAMP96_DATA_LENGTH>::decode_borrowed_with_format(format, reader)?;
68 let timestamp = ext.try_into().map_err(|_| DecodeError::InvalidData)?;
69 Ok(timestamp)
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76 use crate::decode::Decode;
77
78 const TIMESTAMP_EXT_TYPE_U8: u8 = 255; #[test]
81 fn decode_success_timestamp32() {
82 let secs: u32 = 1234567890;
83 let mut buf = vec![0xd6, TIMESTAMP_EXT_TYPE_U8];
84 buf.extend_from_slice(&secs.to_be_bytes());
85
86 let mut r = crate::io::SliceReader::new(&buf);
87 let ts = Timestamp32::decode(&mut r).unwrap();
88 assert_eq!(ts.seconds(), secs);
89 assert!(r.rest().is_empty());
90 }
91
92 #[test]
93 fn decode_failed_timestamp32_invalid_ext_type() {
94 let secs: u32 = 1;
95 let mut buf = vec![0xd6, 0]; buf.extend_from_slice(&secs.to_be_bytes());
97
98 let mut r = crate::io::SliceReader::new(&buf);
99 let err = Timestamp32::decode(&mut r).unwrap_err();
100 assert_eq!(err, DecodeError::InvalidData);
101 }
102
103 #[test]
104 fn decode_failed_timestamp32_eof_data() {
105 let secs: u32 = 123;
106 let mut buf = vec![0xd6, TIMESTAMP_EXT_TYPE_U8];
107 buf.extend_from_slice(&secs.to_be_bytes()[..3]); let mut r = crate::io::SliceReader::new(&buf);
110 let err = Timestamp32::decode(&mut r).unwrap_err();
111 assert!(matches!(err, DecodeError::Io(_)));
112 }
113
114 #[test]
115 fn decode_success_timestamp64() {
116 let secs: u64 = 1234567890;
117 let nanos: u32 = 789;
118
119 let data = ((nanos as u64) << 34) | secs;
120 let mut buf = vec![0xd7, TIMESTAMP_EXT_TYPE_U8];
121 buf.extend_from_slice(&data.to_be_bytes());
122
123 let mut r = crate::io::SliceReader::new(&buf);
124 let ts = Timestamp64::decode(&mut r).unwrap();
125 assert_eq!(ts.seconds(), secs);
126 assert_eq!(ts.nanos(), nanos);
127 assert!(r.rest().is_empty());
128 }
129
130 #[test]
131 fn decode_failed_timestamp64_unexpected_format() {
132 let mut buf = vec![0xd6, TIMESTAMP_EXT_TYPE_U8]; buf.extend_from_slice(&0u64.to_be_bytes());
134
135 let mut r = crate::io::SliceReader::new(&buf);
136 let err = Timestamp64::decode(&mut r).unwrap_err();
137 assert_eq!(err, DecodeError::UnexpectedFormat);
138 }
139
140 #[test]
141 fn decode_failed_timestamp64_invalid_ext_type() {
142 let mut buf = vec![0xd7, 0]; buf.extend_from_slice(&0u64.to_be_bytes());
144
145 let mut r = crate::io::SliceReader::new(&buf);
146 let err = Timestamp64::decode(&mut r).unwrap_err();
147 assert_eq!(err, DecodeError::InvalidData);
148 }
149
150 #[test]
151 fn decode_failed_timestamp64_eof_data() {
152 let mut buf = vec![0xd7, TIMESTAMP_EXT_TYPE_U8];
153 buf.extend_from_slice(&[0u8; 7]); let mut r = crate::io::SliceReader::new(&buf);
156 let err = Timestamp64::decode(&mut r).unwrap_err();
157 assert!(matches!(err, DecodeError::Io(_)));
158 }
159
160 #[test]
161 fn decode_failed_timestamp64_invalid_nanos() {
162 let secs: u64 = 0;
164 let nanos: u64 = 1_000_000_000;
165 let data = (nanos << 34) | secs;
166 let mut buf = vec![0xd7, TIMESTAMP_EXT_TYPE_U8];
167 buf.extend_from_slice(&data.to_be_bytes());
168
169 let mut r = crate::io::SliceReader::new(&buf);
170 let err = Timestamp64::decode(&mut r).unwrap_err();
171 assert_eq!(err, DecodeError::InvalidData);
172 }
173
174 #[test]
175 fn decode_success_timestamp96_positive() {
176 let secs: i64 = 123456;
177 let nanos: u32 = 789;
178
179 let mut buf = vec![0xc7, 12, TIMESTAMP_EXT_TYPE_U8];
180 buf.extend_from_slice(&nanos.to_be_bytes());
181 buf.extend_from_slice(&secs.to_be_bytes());
182
183 let mut r = crate::io::SliceReader::new(&buf);
184 let ts = Timestamp96::decode(&mut r).unwrap();
185 assert_eq!(ts.seconds(), secs);
186 assert_eq!(ts.nanos(), nanos);
187 assert!(r.rest().is_empty());
188 }
189
190 #[test]
191 fn decode_success_timestamp96_negative() {
192 let secs: i64 = -123;
193 let nanos: u32 = 42;
194
195 let mut buf = vec![0xc7, 12, TIMESTAMP_EXT_TYPE_U8];
196 buf.extend_from_slice(&nanos.to_be_bytes());
197 buf.extend_from_slice(&secs.to_be_bytes());
198
199 let mut r = crate::io::SliceReader::new(&buf);
200 let ts = Timestamp96::decode(&mut r).unwrap();
201 assert_eq!(ts.seconds(), secs);
202 assert_eq!(ts.nanos(), nanos);
203 assert!(r.rest().is_empty());
204 }
205
206 #[test]
207 fn decode_failed_timestamp96_unexpected_format() {
208 let mut buf = vec![0xd7, TIMESTAMP_EXT_TYPE_U8];
210 buf.extend_from_slice(&[0u8; 8]);
211
212 let mut r = crate::io::SliceReader::new(&buf);
213 let err = Timestamp96::decode(&mut r).unwrap_err();
214 assert_eq!(err, DecodeError::UnexpectedFormat);
215 }
216
217 #[test]
218 fn decode_failed_timestamp96_invalid_length() {
219 let mut buf = vec![0xc7, 11, TIMESTAMP_EXT_TYPE_U8];
221 buf.extend_from_slice(&[0u8; 11]);
222
223 let mut r = crate::io::SliceReader::new(&buf);
224 let err = Timestamp96::decode(&mut r).unwrap_err();
225 assert_eq!(err, DecodeError::InvalidData);
226 }
227
228 #[test]
229 fn decode_failed_timestamp96_invalid_ext_type() {
230 let secs: i64 = 1;
231 let nanos: u32 = 2;
232
233 let mut buf = vec![0xc7, 12, 0]; buf.extend_from_slice(&nanos.to_be_bytes());
235 buf.extend_from_slice(&secs.to_be_bytes());
236
237 let mut r = crate::io::SliceReader::new(&buf);
238 let err = Timestamp96::decode(&mut r).unwrap_err();
239 assert_eq!(err, DecodeError::InvalidData);
240 }
241
242 #[test]
243 fn decode_failed_timestamp96_eof_data() {
244 let mut buf = vec![0xc7, 12, TIMESTAMP_EXT_TYPE_U8];
246 buf.extend_from_slice(&[0u8; 11]);
247
248 let mut r = crate::io::SliceReader::new(&buf);
249 let err = Timestamp96::decode(&mut r).unwrap_err();
250 assert!(matches!(err, DecodeError::Io(_)));
251 }
252
253 #[test]
254 fn decode_failed_timestamp96_invalid_nanos() {
255 let nanos: u32 = 1_000_000_000;
257 let secs: i64 = 0;
258 let mut buf = vec![0xc7, 12, TIMESTAMP_EXT_TYPE_U8];
259 buf.extend_from_slice(&nanos.to_be_bytes());
260 buf.extend_from_slice(&secs.to_be_bytes());
261
262 let mut r = crate::io::SliceReader::new(&buf);
263 let err = Timestamp96::decode(&mut r).unwrap_err();
264 assert_eq!(err, DecodeError::InvalidData);
265 }
266}