1#[cfg(feature = "timestamp")]
2pub mod timestamp;
3
4use crate::encode::{Binary, Error, SerializeIntoSlice};
5#[allow(unused_imports)]
6use crate::marker::Marker;
7#[allow(unused_imports)]
8use byteorder::{BigEndian, ByteOrder};
9use core::{convert::TryInto, fmt::Display, marker::PhantomData};
10use serde::{ser::SerializeStruct, Deserialize, Serialize};
11
12#[repr(transparent)]
13#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
14#[cfg_attr(any(test, feature = "derive-debug"), derive(core::fmt::Debug))]
15#[serde(transparent)]
16struct ExtType(i8);
17
18impl Display for ExtType {
19 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
20 if self.0 == -1 {
21 f.write_str("-1 (Timestamp)")
22 } else {
23 write!(f, "{}", self.0)
24 }
25 }
26}
27
28#[derive(PartialEq, Eq)]
29#[cfg_attr(any(test, feature = "derive-debug"), derive(core::fmt::Debug))]
30pub struct Ext<'a> {
31 typ: ExtType,
32 data: Binary<'a>,
33}
34
35impl<'a> Ext<'a> {
36 pub const fn new_from_binary(typ: i8, data: Binary<'a>) -> Self {
37 Ext {
38 typ: ExtType(typ),
39 data: data,
40 }
41 }
42 pub const fn new(typ: i8, data: &'a [u8]) -> Self {
43 Ext {
44 typ: ExtType(typ),
45 data: Binary::new(data),
46 }
47 }
48 #[inline(always)]
49 pub const fn get_type(&self) -> i8 { self.typ.0 }
50 #[inline(always)]
51 pub const fn get_data(&self) -> &Binary<'a> { &self.data }
52}
53
54#[inline]
55pub(crate) fn get_ext_start(data_len: usize) -> Result<(Marker, usize), Error> {
56 let (marker, header_len) = match data_len {
57 #[cfg(feature = "fixext")]
58 1 | 2 | 4 | 8 | 16 => {
59 let header_len = 2;
60 let marker = match data_len {
61 1 => Marker::FixExt1,
62 2 => Marker::FixExt2,
63 4 => Marker::FixExt4,
64 8 => Marker::FixExt8,
65 16 => Marker::FixExt16,
66 _ => unreachable!(),
67 };
68 (marker, header_len)
69 }
70 #[cfg(feature = "ext8")]
71 0..=0xff => (Marker::Ext8, 3),
72 #[cfg(feature = "ext16")]
73 0x100..=0xffff => (Marker::Ext16, 4),
74 #[cfg(feature = "ext32")]
75 0x1_0000..=0xffff_ffff => (Marker::Ext32, 6),
76 _ => return Err(Error::OutOfBounds),
77 };
78 Ok((marker, header_len))
79}
80
81pub(crate) fn read_ext_len<B: zerocopy::ByteSlice>(buf: B) -> Result<(usize, usize), crate::decode::Error> {
82 if buf.len() < 2 {
83 return Err(crate::decode::Error::EndOfBuffer);
84 }
85 let marker: Marker = buf[0].try_into().unwrap();
86 let (header_len, data_len) = match marker {
87 #[cfg(feature = "fixext")]
88 Marker::FixExt1 => (2, 1),
89 #[cfg(feature = "fixext")]
90 Marker::FixExt2 => (2, 2),
91 #[cfg(feature = "fixext")]
92 Marker::FixExt4 => (2, 4),
93 #[cfg(feature = "fixext")]
94 Marker::FixExt8 => (2, 8),
95 #[cfg(feature = "fixext")]
96 Marker::FixExt16 => (2, 16),
97 #[cfg(feature = "ext8")]
98 Marker::Ext8 => (3, buf[1] as usize),
99 #[cfg(feature = "ext16")]
100 Marker::Ext16 => {
101 if buf.len() < 4 {
102 return Err(crate::decode::Error::EndOfBuffer);
103 }
104 (4, BigEndian::read_u16(&buf[1..3]) as usize)
105 }
106 #[cfg(feature = "ext32")]
107 Marker::Ext32 => {
108 if buf.len() < 6 {
109 return Err(crate::decode::Error::EndOfBuffer);
110 }
111 (6, BigEndian::read_u32(&buf[1..5]) as usize)
112 }
113 _ => return Err(crate::decode::Error::InvalidType),
114 };
115 if buf.len() >= header_len + data_len {
117 Ok((header_len, data_len))
118 } else {
119 Err(crate::decode::Error::EndOfBuffer)
120 }
121}
122
123pub fn serialize_ext<'a>(value: &Ext<'a>, buf: &mut [u8]) -> Result<usize, Error> {
124 let typ = value.get_type();
125 let data = value.get_data();
126
127 let (marker, header_len) = get_ext_start(data.len())?;
128 if buf.len() < data.len() + header_len {
129 return Err(Error::EndOfBuffer);
130 }
131 buf[0] = marker.to_u8();
132 if header_len > 2 {
133 #[cfg(all(feature = "ext8", not(any(feature = "ext16", feature = "ext32"))))]
134 {
135 buf[1] = data.len() as u8;
136 }
137 #[cfg(any(feature = "ext16", feature = "ext32"))]
138 {
139 BigEndian::write_uint(&mut buf[1..], data.len() as u64, header_len - 2);
140 }
141 }
142 buf[header_len - 1] = typ as u8;
143 buf[header_len..data.len() + header_len].clone_from_slice(&data);
144 Ok(data.len() + header_len)
145}
146
147pub fn try_deserialize_ext<'a>(buf: &'a [u8]) -> Result<Ext<'a>, crate::decode::Error> {
148 if buf.len() < 3 {
149 return Err(crate::decode::Error::EndOfBuffer);
150 }
151 let (header_len, data_len) = read_ext_len(&buf[..])?;
152 if buf.len() < header_len + data_len {
153 return Err(crate::decode::Error::EndOfBuffer);
154 }
155 let typ = buf[header_len - 1] as i8;
156 return Ok(Ext::new(typ, &buf[header_len..header_len + data_len]));
157}
158
159impl<'a> SerializeIntoSlice for &Ext<'a> {
160 fn write_into_slice(&self, buf: &mut [u8]) -> Result<usize, Error> { serialize_ext(self, buf) }
161}
162
163pub(crate) const TYPE_NAME: &'static str = "$Ext";
164pub(crate) const FIELD_TYPE_NAME: &'static str = "type";
165pub(crate) const FIELD_DATA_NAME: &'static str = "data";
166
167#[cfg(feature = "serde")]
168impl<'a> ::serde::ser::Serialize for Ext<'a> {
169 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
170 where S: serde::Serializer {
171 let mut s = serializer.serialize_struct(TYPE_NAME, 2)?;
172 s.serialize_field(FIELD_TYPE_NAME, &self.typ)?;
173 s.serialize_field(FIELD_DATA_NAME, &self.data)?;
174 s.end()
175 }
176}
177
178#[cfg(feature = "serde")]
179impl<'de: 'a, 'a> ::serde::de::Deserialize<'de> for Ext<'a> {
180 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
181 where D: ::serde::de::Deserializer<'de> {
182 struct ExtVisitor<'a>(PhantomData<&'a ()>);
183
184 impl<'de: 'a, 'a> ::serde::de::Visitor<'de> for ExtVisitor<'a> {
185 type Value = Ext<'a>;
186 fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { formatter.write_str("a MsgPack ext data") }
187 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
188 where A: serde::de::SeqAccess<'de> {
189 let typ: Option<ExtType> = seq.next_element()?;
192 let data: Option<Binary> = seq.next_element()?;
193 match (typ, data) {
194 (Some(typ), Some(data)) => Ok(Ext::new_from_binary(typ.0, data)),
195 (Some(_), None) => Err(::serde::de::Error::custom("ext data not found")),
196 _ => Err(::serde::de::Error::custom("ext type field not found")),
197 }
198 }
199 fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
200 where V: ::serde::de::MapAccess<'de> {
201 enum Field {
205 Type,
208 Data,
209 }
210
211 impl<'de> ::serde::de::Deserialize<'de> for Field {
212 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
213 where D: serde::Deserializer<'de> {
214 struct FieldVisitor;
215 impl<'de> ::serde::de::Visitor<'de> for FieldVisitor {
216 type Value = Field;
217 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
218 formatter.write_str("`type` or `data`")
220 }
221 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
222 where E: serde::de::Error {
223 match v {
224 "type" => Ok(Field::Type),
227 "data" => Ok(Field::Data),
228 _ => Err(::serde::de::Error::unknown_field(
229 v,
230 &["type", "data"],
231 )),
233 }
234 }
235 }
236
237 deserializer.deserialize_identifier(FieldVisitor)
238 }
239 }
240
241 let mut typ = None;
250 let mut data = None;
251 loop {
255 match map.next_key::<Field>() {
256 Ok(Some(Field::Type)) => typ = Some(map.next_value::<ExtType>()?),
257 Ok(Some(Field::Data)) => data = Some(map.next_value::<Binary>()?),
258 Ok(None) => break, Err(_e) => {
260 map.next_value()?;
263 }
264 }
265 }
266
267 match (typ, data) {
268 (Some(typ), Some(data)) => Ok(Ext::new_from_binary(typ.0, data)),
269 (Some(_), None) => Err(::serde::de::Error::custom("ext data not found")),
270 _ => Err(::serde::de::Error::custom("ext type field not found")),
271 }
272 }
274 }
275
276 static FIELDS: [&str; 2] = [FIELD_TYPE_NAME, FIELD_DATA_NAME];
277 deserializer.deserialize_struct(TYPE_NAME, &FIELDS, ExtVisitor(PhantomData))
278 }
279}