embedded_msgpack/ext/
mod.rs

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    // let typ = buf[header_len - 1] as i8;
116    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                // This will be called from the MsgPack deserializer
190                // if it detects an ext tag or an array tag
191                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                // This will probably be called from other deserializers
202                // or if the MsgPack deserializer sees a map tag
203
204                enum Field {
205                    // Seconds,
206                    // Nanoseconds,
207                    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("`seconds`, `secs`, `s`, `nanoseconds`, `nanos` or `ns`")
219                                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                                    // "seconds" | "secs" | "s" => Ok(Field::Seconds),
225                                    // "nanoseconds" | "nanos" | "ns" => Ok(Field::Nanoseconds),
226                                    "type" => Ok(Field::Type),
227                                    "data" => Ok(Field::Data),
228                                    _ => Err(::serde::de::Error::unknown_field(
229                                        v,
230                                        &["type", "data"],
231                                        // &["seconds", "secs", "s", "nanoseconds", "nanos", "ns"],
232                                    )),
233                                }
234                            }
235                        }
236
237                        deserializer.deserialize_identifier(FieldVisitor)
238                    }
239                }
240
241                // if let Ok(typ) = map.next_key::<Field>() {
242                //     let typ = match typ {
243                //         Some(v) => v,
244                //         None => return Err(::serde::de::Error::custom("ext type not found")),
245                //     };
246                //     let v: Binary = map.next_value()?;
247                //     Ok(Ext::new(typ.0, &v))
248                // } else {
249                let mut typ = None;
250                let mut data = None;
251                // let mut seconds = None;
252                // let mut nanoseconds = None;
253
254                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, // no more fields
259                        Err(_e) => {
260                            // Error, could be an unknown field name
261                            // println!("{:?}", e);
262                            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                // }
273            }
274        }
275
276        static FIELDS: [&str; 2] = [FIELD_TYPE_NAME, FIELD_DATA_NAME];
277        deserializer.deserialize_struct(TYPE_NAME, &FIELDS, ExtVisitor(PhantomData))
278    }
279}