1use super::{Decode, Error, NbyteReader, Result};
2use crate::{
3 Format,
4 timestamp::{TIMESTAMP_EXTENSION_TYPE, Timestamp32, Timestamp64, Timestamp96},
5};
6
7impl<'a> Decode<'a> for Timestamp32 {
8 type Value = Timestamp32;
9 fn decode(buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
10 let (format, buf) = Format::decode(buf)?;
11 match format {
12 Format::FixExt4 => Self::decode_with_format(format, buf),
13 _ => Err(Error::UnexpectedFormat),
14 }
15 }
16 fn decode_with_format(format: crate::Format, buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
17 let (len, buf) = match format {
18 Format::FixExt4 => (4, buf),
19 _ => return Err(Error::UnexpectedFormat),
20 };
21 let (ext_type, buf) = buf.split_first().ok_or(Error::EofData)?;
22 let ext_type = (*ext_type) as i8;
23 if ext_type != TIMESTAMP_EXTENSION_TYPE {
24 return Err(Error::InvalidData);
25 }
26
27 let (data, rest) = buf.split_at_checked(len).ok_or(Error::EofData)?;
28 let timestamp = Self::from_buf(data.try_into().expect("expect 4 len"));
29 Ok((timestamp, rest))
30 }
31}
32
33impl<'a> Decode<'a> for Timestamp64 {
34 type Value = Timestamp64;
35 fn decode(buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
36 let (format, buf) = Format::decode(buf)?;
37 match format {
38 Format::FixExt8 => Self::decode_with_format(format, buf),
39 _ => Err(Error::UnexpectedFormat),
40 }
41 }
42 fn decode_with_format(format: crate::Format, buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
43 let (len, buf) = match format {
44 Format::FixExt8 => (8, buf),
45 _ => return Err(Error::UnexpectedFormat),
46 };
47 let (ext_type, buf) = buf.split_first().ok_or(Error::EofData)?;
48 let ext_type = (*ext_type) as i8;
49 if ext_type != TIMESTAMP_EXTENSION_TYPE {
50 return Err(Error::InvalidData);
51 }
52
53 let (data, rest) = buf.split_at_checked(len).ok_or(Error::EofData)?;
54 let timestamp = Self::from_buf(data.try_into().expect("expect 8 len"));
55 Ok((timestamp, rest))
56 }
57}
58
59impl<'a> Decode<'a> for Timestamp96 {
60 type Value = Timestamp96;
61 fn decode(buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
62 let (format, buf) = Format::decode(buf)?;
63 match format {
64 Format::Ext8 => Self::decode_with_format(format, buf),
65 _ => Err(Error::UnexpectedFormat),
66 }
67 }
68 fn decode_with_format(format: crate::Format, buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
69 let (len, buf) = match format {
70 Format::Ext8 => NbyteReader::<1>::read(buf)?,
71 _ => return Err(Error::UnexpectedFormat),
72 };
73 const TIMESTAMP96_DATA_LENGTH: usize = 12;
74 if len != TIMESTAMP96_DATA_LENGTH {
75 return Err(Error::InvalidData);
76 }
77
78 let (ext_type, buf) = buf.split_first().ok_or(Error::EofData)?;
79 let ext_type = (*ext_type) as i8;
80 if ext_type != TIMESTAMP_EXTENSION_TYPE {
81 return Err(Error::InvalidData);
82 }
83
84 let (data, rest) = buf.split_at_checked(len).ok_or(Error::EofData)?;
85 let timestamp = Self::from_buf(data.try_into().expect("expect 12 len"));
86 Ok((timestamp, rest))
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93 const TIMESTAMP_EXT_TYPE: u8 = 255; #[test]
96 fn decode_success_timestamp32() {
97 let secs: u32 = 1234567890;
98 let mut buf = vec![0xd6, TIMESTAMP_EXT_TYPE];
99 buf.extend_from_slice(&secs.to_be_bytes());
100
101 let (ts, rest) = Timestamp32::decode(&buf).unwrap();
102 assert_eq!(ts.seconds(), secs);
103 assert!(rest.is_empty());
104 }
105
106 #[test]
107 fn decode_failed_timestamp32_invalid_ext_type() {
108 let secs: u32 = 1;
109 let mut buf = vec![0xd6, 0]; buf.extend_from_slice(&secs.to_be_bytes());
111
112 let err = Timestamp32::decode(&buf).unwrap_err();
113 assert_eq!(err, Error::InvalidData);
114 }
115
116 #[test]
117 fn decode_failed_timestamp32_eof_data() {
118 let secs: u32 = 123;
119 let mut buf = vec![0xd6, TIMESTAMP_EXT_TYPE];
120 buf.extend_from_slice(&secs.to_be_bytes()[..3]); let err = Timestamp32::decode(&buf).unwrap_err();
123 assert_eq!(err, Error::EofData);
124 }
125
126 #[test]
127 fn decode_success_timestamp64() {
128 let secs: u64 = 1234567890;
129 let nanos: u32 = 789;
130
131 let data = ((nanos as u64) << 34) | secs;
132 let mut buf = vec![0xd7, TIMESTAMP_EXT_TYPE];
133 buf.extend_from_slice(&data.to_be_bytes());
134
135 let (ts, rest) = Timestamp64::decode(&buf).unwrap();
136 assert_eq!(ts.seconds(), secs);
137 assert_eq!(ts.nanos(), nanos);
138 assert!(rest.is_empty());
139 }
140
141 #[test]
142 fn decode_failed_timestamp64_unexpected_format() {
143 let mut buf = vec![0xd6, TIMESTAMP_EXT_TYPE]; buf.extend_from_slice(&0u64.to_be_bytes());
145
146 let err = Timestamp64::decode(&buf).unwrap_err();
147 assert_eq!(err, Error::UnexpectedFormat);
148 }
149
150 #[test]
151 fn decode_failed_timestamp64_invalid_ext_type() {
152 let mut buf = vec![0xd7, 0]; buf.extend_from_slice(&0u64.to_be_bytes());
154
155 let err = Timestamp64::decode(&buf).unwrap_err();
156 assert_eq!(err, Error::InvalidData);
157 }
158
159 #[test]
160 fn decode_failed_timestamp64_eof_data() {
161 let mut buf = vec![0xd7, TIMESTAMP_EXT_TYPE];
162 buf.extend_from_slice(&[0u8; 7]); let err = Timestamp64::decode(&buf).unwrap_err();
165 assert_eq!(err, Error::EofData);
166 }
167
168 #[test]
169 fn decode_success_timestamp96_positive() {
170 let secs: i64 = 123456;
171 let nanos: u32 = 789;
172
173 let mut buf = vec![0xc7, 12, TIMESTAMP_EXT_TYPE];
174 buf.extend_from_slice(&nanos.to_be_bytes());
175 buf.extend_from_slice(&secs.to_be_bytes());
176
177 let (ts, rest) = Timestamp96::decode(&buf).unwrap();
178 assert_eq!(ts.seconds(), secs);
179 assert_eq!(ts.nanos(), nanos);
180 assert!(rest.is_empty());
181 }
182
183 #[test]
184 fn decode_success_timestamp96_negative() {
185 let secs: i64 = -123;
186 let nanos: u32 = 42;
187
188 let mut buf = vec![0xc7, 12, TIMESTAMP_EXT_TYPE];
189 buf.extend_from_slice(&nanos.to_be_bytes());
190 buf.extend_from_slice(&secs.to_be_bytes());
191
192 let (ts, rest) = Timestamp96::decode(&buf).unwrap();
193 assert_eq!(ts.seconds(), secs);
194 assert_eq!(ts.nanos(), nanos);
195 assert!(rest.is_empty());
196 }
197
198 #[test]
199 fn decode_failed_timestamp96_unexpected_format() {
200 let mut buf = vec![0xd7, TIMESTAMP_EXT_TYPE];
202 buf.extend_from_slice(&[0u8; 8]);
203
204 let err = Timestamp96::decode(&buf).unwrap_err();
205 assert_eq!(err, Error::UnexpectedFormat);
206 }
207
208 #[test]
209 fn decode_failed_timestamp96_invalid_length() {
210 let mut buf = vec![0xc7, 11, TIMESTAMP_EXT_TYPE];
212 buf.extend_from_slice(&[0u8; 11]);
213
214 let err = Timestamp96::decode(&buf).unwrap_err();
215 assert_eq!(err, Error::InvalidData);
216 }
217
218 #[test]
219 fn decode_failed_timestamp96_invalid_ext_type() {
220 let secs: i64 = 1;
221 let nanos: u32 = 2;
222
223 let mut buf = vec![0xc7, 12, 0]; buf.extend_from_slice(&nanos.to_be_bytes());
225 buf.extend_from_slice(&secs.to_be_bytes());
226
227 let err = Timestamp96::decode(&buf).unwrap_err();
228 assert_eq!(err, Error::InvalidData);
229 }
230
231 #[test]
232 fn decode_failed_timestamp96_eof_data() {
233 let mut buf = vec![0xc7, 12, TIMESTAMP_EXT_TYPE];
235 buf.extend_from_slice(&[0u8; 11]);
236
237 let err = Timestamp96::decode(&buf).unwrap_err();
238 assert_eq!(err, Error::EofData);
239 }
240}