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