messagepack_core/extension/
decode.rs1use super::{ExtensionRef, FixedExtension, read_ext_header};
2use crate::Format;
3use crate::decode::{DecodeBorrowed, Error as DecodeError};
4use crate::io::IoRead;
5
6impl<'de> DecodeBorrowed<'de> for ExtensionRef<'de> {
7 type Value = ExtensionRef<'de>;
8
9 fn decode_borrowed_with_format<R>(
10 format: Format,
11 reader: &mut R,
12 ) -> core::result::Result<Self::Value, DecodeError<R::Error>>
13 where
14 R: IoRead<'de>,
15 {
16 let (len, ext_type) = read_ext_header(format, reader)?;
17
18 let data_ref = reader.read_slice(len).map_err(DecodeError::Io)?;
19 let data = match data_ref {
20 crate::io::Reference::Borrowed(b) => b,
21 crate::io::Reference::Copied(_) => return Err(DecodeError::InvalidData),
22 };
23 Ok(ExtensionRef {
24 r#type: ext_type,
25 data,
26 })
27 }
28}
29
30impl<'de, const N: usize> DecodeBorrowed<'de> for FixedExtension<N> {
31 type Value = FixedExtension<N>;
32
33 fn decode_borrowed_with_format<R>(
34 format: Format,
35 reader: &mut R,
36 ) -> core::result::Result<Self::Value, DecodeError<R::Error>>
37 where
38 R: IoRead<'de>,
39 {
40 let (len, ext_type) = read_ext_header(format, reader)?;
41
42 if len > N {
43 return Err(DecodeError::InvalidData);
44 }
45
46 let payload = reader.read_slice(len).map_err(DecodeError::Io)?;
47 let bytes = payload.as_bytes();
48 if bytes.len() != len {
49 return Err(DecodeError::UnexpectedEof);
50 }
51
52 let mut data = [0u8; N];
53 data[..len].copy_from_slice(bytes);
54
55 Ok(FixedExtension {
56 r#type: ext_type,
57 len,
58 data,
59 })
60 }
61}
62
63#[cfg(feature = "alloc")]
64impl<'de> DecodeBorrowed<'de> for super::owned::ExtensionOwned {
65 type Value = super::owned::ExtensionOwned;
66
67 fn decode_borrowed_with_format<R>(
68 format: Format,
69 reader: &mut R,
70 ) -> core::result::Result<Self::Value, DecodeError<R::Error>>
71 where
72 R: crate::io::IoRead<'de>,
73 {
74 let (len, ext_type) = read_ext_header(format, reader)?;
75
76 let payload = reader.read_slice(len).map_err(DecodeError::Io)?;
77 let data = payload.as_bytes().to_vec();
78
79 Ok(super::owned::ExtensionOwned {
80 r#type: ext_type,
81 data,
82 })
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89 use crate::decode::Decode;
90 use crate::encode::Encode;
91
92 #[rstest::rstest]
93 #[case(crate::Format::FixExt1.as_byte(), 5_i8, [0x12])]
94 #[case(crate::Format::FixExt2.as_byte(), -1_i8, [0x34, 0x56])]
95 #[case(crate::Format::FixExt4.as_byte(), 42_i8, [0xde, 0xad, 0xbe, 0xef])]
96 #[case(crate::Format::FixExt8.as_byte(), -7_i8, [0xAA; 8])]
97 #[case(crate::Format::FixExt16.as_byte(), 7_i8, [0x55; 16])]
98 fn decode_ext_fixed<E: AsRef<[u8]>>(#[case] marker: u8, #[case] ty: i8, #[case] data: E) {
99 let buf = core::iter::once(marker)
101 .chain(core::iter::once(ty as u8))
102 .chain(data.as_ref().iter().cloned())
103 .collect::<Vec<u8>>();
104
105 let mut r = crate::io::SliceReader::new(&buf);
106 let ext = ExtensionRef::decode(&mut r).unwrap();
107 assert_eq!(ext.r#type, ty);
108 assert_eq!(ext.data, data.as_ref());
109 assert!(r.rest().is_empty());
110 }
111
112 #[rstest::rstest]
113 #[case(crate::Format::Ext8, 42_i8, 5u8.to_be_bytes(), [0x11;5])] #[case(crate::Format::Ext16, -7_i8, 300u16.to_be_bytes(), [0xAA;300])] #[case(crate::Format::Ext32, 7_i8, 70000u32.to_be_bytes(), [0x55;70000])] fn decode_ext_sized<S: AsRef<[u8]>, D: AsRef<[u8]>>(
117 #[case] format: crate::Format,
118 #[case] ty: i8,
119 #[case] size: S,
120 #[case] data: D,
121 ) {
122 let buf = format
124 .as_slice()
125 .iter()
126 .chain(size.as_ref())
127 .chain(ty.to_be_bytes().iter())
128 .chain(data.as_ref())
129 .cloned()
130 .collect::<Vec<_>>();
131
132 let mut r = crate::io::SliceReader::new(&buf);
133 let ext = ExtensionRef::decode(&mut r).unwrap();
134 assert_eq!(ext.r#type, ty);
135 assert_eq!(ext.data, data.as_ref());
136 assert!(r.rest().is_empty());
137 }
138
139 #[rstest::rstest]
140 fn fixed_extension_roundtrip() {
141 let data = [1u8, 2, 3, 4];
142 let ext = FixedExtension::<8>::new(5, &data).unwrap();
143 let mut buf = vec![];
144 ext.encode(&mut buf).unwrap();
145 let mut r = crate::io::SliceReader::new(&buf);
146 let decoded = FixedExtension::<8>::decode(&mut r).unwrap();
147 assert_eq!(decoded.r#type, 5);
148 assert_eq!(decoded.as_slice(), &data);
149 assert!(r.rest().is_empty());
150 }
151
152 #[cfg(feature = "std")]
153 #[rstest::rstest]
154 fn fixed_extension_decode_with_std_reader_copied() {
155 let mut buf = vec![];
157 buf.extend_from_slice(&[crate::Format::Ext8.as_byte(), 5u8, 7u8]);
158 buf.extend_from_slice(&[9u8; 5]);
159
160 let cursor = std::io::Cursor::new(buf);
162 let mut r = crate::io::StdReader::new(cursor);
163
164 let decoded = FixedExtension::<8>::decode(&mut r).unwrap();
165 assert_eq!(decoded.r#type, 7);
166 assert_eq!(decoded.as_slice(), &[9u8; 5]);
167 }
168
169 #[cfg(feature = "std")]
170 #[rstest::rstest]
171 fn extension_owned_decode_with_std_reader_copied() {
172 let mut buf = vec![];
174 buf.extend_from_slice(&[crate::Format::Ext8.as_byte(), 3u8, (!5u8) + 1]); buf.extend_from_slice(&[0xAA, 0xBB, 0xCC]);
176
177 let cursor = std::io::Cursor::new(buf);
178 let mut r = crate::io::StdReader::new(cursor);
179
180 let ext = super::super::ExtensionOwned::decode(&mut r).unwrap();
181 assert_eq!(ext.r#type, -5);
182 assert_eq!(ext.data, vec![0xAA, 0xBB, 0xCC]);
183 }
184}