messagepack_core/decode/
extension.rs1use super::{Decode, Error, NbyteReader, Result};
2use crate::formats::Format;
3
4pub struct Extension<'a> {
5 pub r#type: i8,
6 pub data: &'a [u8],
7}
8
9pub struct ExtensionDecoder;
10
11impl<'a> Decode<'a> for ExtensionDecoder {
12 type Value = Extension<'a>;
13 fn decode(buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
14 let (format, buf) = Format::decode(buf)?;
15 match format {
16 Format::FixExt1
17 | Format::FixExt2
18 | Format::FixExt4
19 | Format::FixExt8
20 | Format::FixExt16
21 | Format::Ext8
22 | Format::Ext16
23 | Format::Ext32 => Self::decode_with_format(format, buf),
24 _ => Err(Error::UnexpectedFormat),
25 }
26 }
27 fn decode_with_format(format: Format, buf: &'a [u8]) -> Result<(Self::Value, &'a [u8])> {
28 let (ext_type, buf) = buf.split_first().ok_or(Error::EofData)?;
29 let (len, buf) = match format {
30 Format::FixExt1 => (1, buf),
31 Format::FixExt2 => (2, buf),
32 Format::FixExt4 => (4, buf),
33 Format::FixExt8 => (8, buf),
34 Format::FixExt16 => (16, buf),
35 Format::Ext8 => NbyteReader::<1>::read(buf)?,
36 Format::Ext16 => NbyteReader::<2>::read(buf)?,
37 Format::Ext32 => NbyteReader::<4>::read(buf)?,
38 _ => return Err(Error::UnexpectedFormat),
39 };
40 let (data, rest) = buf.split_at_checked(len).ok_or(Error::EofData)?;
41 let ext = Extension {
42 r#type: (*ext_type) as i8,
43 data,
44 };
45 Ok((ext, rest))
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 const TIMESTAMP32: &[u8] = &[
54 0xd6, 0xff, 0x62, 0x15, 0x62, 0x1e,
59 ];
60
61 #[test]
62 fn decode_fix_ext4() {
63 let (ext, rest) = ExtensionDecoder::decode(TIMESTAMP32).unwrap();
64
65 let expect_type = -1;
66 let expect_data = 1645568542;
67 assert_eq!(ext.r#type, expect_type);
68 let data_u32 = u32::from_be_bytes(ext.data.try_into().unwrap());
69 assert_eq!(data_u32, expect_data);
70 assert_eq!(rest.len(), 0);
71 }
72}