messagepack_rs/
serializable.rs

1use byteorder::{BigEndian, WriteBytesExt};
2use chrono::prelude::*;
3use crate::binary::Binary;
4use crate::extension::Extension;
5use crate::marker::Marker;
6use std::collections::BTreeMap;
7use std::io::Write;
8
9#[derive(Debug)]
10pub enum SerializeError {
11    FailedToWrite,
12    OutOfRange,
13}
14
15pub trait Serializable: Sized {
16    fn serialize(self) -> Result<Vec<u8>, SerializeError>;
17
18    fn serialize_nil() -> Result<Vec<u8>, SerializeError> {
19        Ok(vec![Marker::Nil.into()])
20    }
21
22    fn serialize_bool(v: bool) -> Result<Vec<u8>, SerializeError> {
23        Ok(if v { vec![Marker::True.into()] } else { vec![Marker::False.into()] })
24    }
25
26    fn serialize_float32(v: f32) -> Result<Vec<u8>, SerializeError> {
27        let mut w = Vec::with_capacity(1 + 4);
28        w.write_u8(Marker::Float32.into()).or(Err(SerializeError::FailedToWrite))?;
29        w.write_f32::<BigEndian>(v).or(Err(SerializeError::FailedToWrite))?;
30        Ok(w)
31    }
32
33    fn serialize_float64(v: f64) -> Result<Vec<u8>, SerializeError> {
34        let mut w = Vec::with_capacity(1 + 8);
35        w.write_u8(Marker::Float64.into()).or(Err(SerializeError::FailedToWrite))?;
36        w.write_f64::<BigEndian>(v).or(Err(SerializeError::FailedToWrite))?;
37        Ok(w)
38    }
39
40    fn serialize_uint8(v: u8) -> Result<Vec<u8>, SerializeError> {
41        if v < 0b1000_0000 {
42            let mut w = Vec::with_capacity(1);
43            w.write_u8(v).or(Err(SerializeError::FailedToWrite))?;
44            Ok(w)
45        } else {
46            let mut w = Vec::with_capacity(1 + 1);
47            w.write_u8(Marker::UInt8.into()).or(Err(SerializeError::FailedToWrite))?;
48            w.write_u8(v).or(Err(SerializeError::FailedToWrite))?;
49            Ok(w)
50        }
51    }
52
53    fn serialize_uint16(v: u16) -> Result<Vec<u8>, SerializeError> {
54        if v < 0b1000_0000 {
55            let mut w = Vec::with_capacity(1);
56            w.write_u8(v as u8).or(Err(SerializeError::FailedToWrite))?;
57            Ok(w)
58        } else if v <= u16::from(u8::max_value()) {
59            let mut w = Vec::with_capacity(1 + 1);
60            w.write_u8(Marker::UInt8.into()).or(Err(SerializeError::FailedToWrite))?;
61            w.write_u8(v as u8).or(Err(SerializeError::FailedToWrite))?;
62            Ok(w)
63        } else {
64            let mut w = Vec::with_capacity(1 + 2);
65            w.write_u8(Marker::UInt16.into()).or(Err(SerializeError::FailedToWrite))?;
66            w.write_u16::<BigEndian>(v).or(Err(SerializeError::FailedToWrite))?;
67            Ok(w)
68        }
69    }
70
71    fn serialize_uint32(v: u32) -> Result<Vec<u8>, SerializeError> {
72        if v < 0b1000_0000 {
73            let mut w = Vec::with_capacity(1);
74            w.write_u8(v as u8).or(Err(SerializeError::FailedToWrite))?;
75            Ok(w)
76        } else if v <= u32::from(u8::max_value()) {
77            let mut w = Vec::with_capacity(1 + 1);
78            w.write_u8(Marker::UInt8.into()).or(Err(SerializeError::FailedToWrite))?;
79            w.write_u8(v as u8).or(Err(SerializeError::FailedToWrite))?;
80            Ok(w)
81        } else if v <= u32::from(u16::max_value()) {
82            let mut w = Vec::with_capacity(1 + 2);
83            w.write_u8(Marker::UInt16.into()).or(Err(SerializeError::FailedToWrite))?;
84            w.write_u16::<BigEndian>(v as u16).or(Err(SerializeError::FailedToWrite))?;
85            Ok(w)
86        } else {
87            let mut w = Vec::with_capacity(1 + 4);
88            w.write_u8(Marker::UInt32.into()).or(Err(SerializeError::FailedToWrite))?;
89            w.write_u32::<BigEndian>(v).or(Err(SerializeError::FailedToWrite))?;
90            Ok(w)
91        }
92    }
93
94    fn serialize_uint64(v: u64) -> Result<Vec<u8>, SerializeError> {
95        if v < 0b1000_0000 {
96            let mut w = Vec::with_capacity(1);
97            w.write_u8(v as u8).or(Err(SerializeError::FailedToWrite))?;
98            Ok(w)
99        } else if v <= u64::from(u8::max_value()) {
100            let mut w = Vec::with_capacity(1 + 1);
101            w.write_u8(Marker::UInt8.into()).or(Err(SerializeError::FailedToWrite))?;
102            w.write_u8(v as u8).or(Err(SerializeError::FailedToWrite))?;
103            Ok(w)
104        } else if v <= u64::from(u16::max_value()) {
105            let mut w = Vec::with_capacity(1 + 2);
106            w.write_u8(Marker::UInt16.into()).or(Err(SerializeError::FailedToWrite))?;
107            w.write_u16::<BigEndian>(v as u16).or(Err(SerializeError::FailedToWrite))?;
108            Ok(w)
109        } else if v <= u64::from(u32::max_value()) {
110            let mut w = Vec::with_capacity(1 + 4);
111            w.write_u8(Marker::UInt32.into()).or(Err(SerializeError::FailedToWrite))?;
112            w.write_u32::<BigEndian>(v as u32).or(Err(SerializeError::FailedToWrite))?;
113            Ok(w)
114        } else {
115            let mut w = Vec::with_capacity(1 + 8);
116            w.write_u8(Marker::UInt64.into()).or(Err(SerializeError::FailedToWrite))?;
117            w.write_u64::<BigEndian>(v).or(Err(SerializeError::FailedToWrite))?;
118            Ok(w)
119        }
120    }
121
122    fn serialize_int8(v: i8) -> Result<Vec<u8>, SerializeError> {
123        if v >= -0b0010_0000 {
124            let mut w = Vec::with_capacity(1);
125            w.write_i8(v).or(Err(SerializeError::FailedToWrite))?;
126            Ok(w)
127        } else {
128            let mut w = Vec::with_capacity(1 + 1);
129            w.write_u8(Marker::Int8.into()).or(Err(SerializeError::FailedToWrite))?;
130            w.write_i8(v).or(Err(SerializeError::FailedToWrite))?;
131            Ok(w)
132        }
133    }
134
135    fn serialize_int16(v: i16) -> Result<Vec<u8>, SerializeError> {
136        if v >= -0b0010_0000 {
137            let mut w = Vec::with_capacity(1);
138            w.write_i8(v as i8).or(Err(SerializeError::FailedToWrite))?;
139            Ok(w)
140        } else if v >= i16::from(i8::min_value()) && v <= i16::from(i8::max_value()) {
141            let mut w = Vec::with_capacity(1 + 1);
142            w.write_u8(Marker::Int8.into()).or(Err(SerializeError::FailedToWrite))?;
143            w.write_i8(v as i8).or(Err(SerializeError::FailedToWrite))?;
144            Ok(w)
145        } else {
146            let mut w = Vec::with_capacity(1 + 2);
147            w.write_u8(Marker::Int16.into()).or(Err(SerializeError::FailedToWrite))?;
148            w.write_i16::<BigEndian>(v).or(Err(SerializeError::FailedToWrite))?;
149            Ok(w)
150        }
151    }
152
153    fn serialize_int32(v: i32) -> Result<Vec<u8>, SerializeError> {
154        if v >= -0b0010_0000 {
155            let mut w = Vec::with_capacity(1);
156            w.write_i8(v as i8).or(Err(SerializeError::FailedToWrite))?;
157            Ok(w)
158        } else if v >= i32::from(i8::min_value()) && v <= i32::from(i8::max_value()) {
159            let mut w = Vec::with_capacity(1 + 1);
160            w.write_u8(Marker::Int8.into()).or(Err(SerializeError::FailedToWrite))?;
161            w.write_i8(v as i8).or(Err(SerializeError::FailedToWrite))?;
162            Ok(w)
163        } else if v >= i32::from(i16::min_value()) && v <= i32::from(i16::max_value()) {
164            let mut w = Vec::with_capacity(1 + 2);
165            w.write_u8(Marker::Int16.into()).or(Err(SerializeError::FailedToWrite))?;
166            w.write_i16::<BigEndian>(v as i16).or(Err(SerializeError::FailedToWrite))?;
167            Ok(w)
168        } else {
169            let mut w = Vec::with_capacity(1 + 4);
170            w.write_u8(Marker::Int32.into()).or(Err(SerializeError::FailedToWrite))?;
171            w.write_i32::<BigEndian>(v).or(Err(SerializeError::FailedToWrite))?;
172            Ok(w)
173        }
174    }
175
176    fn serialize_int64(v: i64) -> Result<Vec<u8>, SerializeError> {
177        if v >= -0b0010_0000 {
178            let mut w = Vec::with_capacity(1);
179            w.write_i8(v as i8).or(Err(SerializeError::FailedToWrite))?;
180            Ok(w)
181        } else if v >= i64::from(i8::min_value()) && v <= i64::from(i8::max_value()) {
182            let mut w = Vec::with_capacity(1 + 1);
183            w.write_u8(Marker::Int8.into()).or(Err(SerializeError::FailedToWrite))?;
184            w.write_i8(v as i8).or(Err(SerializeError::FailedToWrite))?;
185            Ok(w)
186        } else if v >= i64::from(i16::min_value()) && v <= i64::from(i16::max_value()) {
187            let mut w = Vec::with_capacity(1 + 2);
188            w.write_u8(Marker::Int16.into()).or(Err(SerializeError::FailedToWrite))?;
189            w.write_i16::<BigEndian>(v as i16).or(Err(SerializeError::FailedToWrite))?;
190            Ok(w)
191        } else if v >= i64::from(i32::min_value()) && v <= i64::from(i32::max_value()) {
192            let mut w = Vec::with_capacity(1 + 4);
193            w.write_u8(Marker::Int32.into()).or(Err(SerializeError::FailedToWrite))?;
194            w.write_i32::<BigEndian>(v as i32).or(Err(SerializeError::FailedToWrite))?;
195            Ok(w)
196        } else {
197            let mut w = Vec::with_capacity(1 + 8);
198            w.write_u8(Marker::Int64.into()).or(Err(SerializeError::FailedToWrite))?;
199            w.write_i64::<BigEndian>(v).or(Err(SerializeError::FailedToWrite))?;
200            Ok(w)
201        }
202    }
203
204    fn serialize_binary(v: Binary) -> Result<Vec<u8>, SerializeError> {
205        let mut w = match v.0.len() {
206            len if u8::max_value() as usize >= len => {
207                let mut w = Vec::with_capacity(1 + 1 + len);
208                w.write_u8(Marker::Bin8.into()).or(Err(SerializeError::FailedToWrite))?;
209                w.write_u8(len as u8).or(Err(SerializeError::FailedToWrite))?;
210                w
211            },
212            len if u16::max_value() as usize >= len => {
213                let mut w = Vec::with_capacity(1 + 2 + len);
214                w.write_u8(Marker::Bin16.into()).or(Err(SerializeError::FailedToWrite))?;
215                w.write_u16::<BigEndian>(len as u16).or(Err(SerializeError::FailedToWrite))?;
216                w
217            },
218            len if u32::max_value() as usize >= len => {
219                let mut w = Vec::with_capacity(1 + 4 + len);
220                w.write_u8(Marker::Bin32.into()).or(Err(SerializeError::FailedToWrite))?;
221                w.write_u32::<BigEndian>(len as u32).or(Err(SerializeError::FailedToWrite))?;
222                w
223            },
224            _ => Err(SerializeError::OutOfRange)?,
225        };
226        w.write_all(&v.0).or(Err(SerializeError::FailedToWrite))?;
227        Ok(w)
228    }
229
230    fn serialize_string(v: String) -> Result<Vec<u8>, SerializeError> {
231        let mut w = match v.len() {
232            len if len <= 31 => {
233                let mut w = Vec::with_capacity(1 + len);
234                w.write_u8(Marker::FixStr(len as u8).into()).or(Err(SerializeError::FailedToWrite))?;
235                w
236            },
237            len if u8::max_value() as usize >= len => {
238                let mut w = Vec::with_capacity(1 + 1 + len);
239                w.write_u8(Marker::Str8.into()).or(Err(SerializeError::FailedToWrite))?;
240                w.write_u8(len as u8).or(Err(SerializeError::FailedToWrite))?;
241                w
242            },
243            len if u16::max_value() as usize >= len => {
244                let mut w = Vec::with_capacity(1 + 2 + len);
245                w.write_u8(Marker::Str16.into()).or(Err(SerializeError::FailedToWrite))?;
246                w.write_u16::<BigEndian>(len as u16).or(Err(SerializeError::FailedToWrite))?;
247                w
248            },
249            len if u32::max_value() as usize >= len => {
250                let mut w = Vec::with_capacity(1 + 4 + len);
251                w.write_u8(Marker::Str32.into()).or(Err(SerializeError::FailedToWrite))?;
252                w.write_u32::<BigEndian>(len as u32).or(Err(SerializeError::FailedToWrite))?;
253                w
254            },
255            _ => Err(SerializeError::OutOfRange)?,
256        };
257        w.write_all(v.as_bytes()).or(Err(SerializeError::FailedToWrite))?;
258        Ok(w)
259    }
260
261    fn serialize_array(v: Vec<Self>) -> Result<Vec<u8>, SerializeError> {
262        let mut values = Vec::new();
263        let len = v.len();
264        for vv in v.into_iter() {
265            values.append(&mut Self::serialize(vv)?);
266        }
267        let mut w = match len {
268            len if len <= 15 => {
269                let mut w = Vec::with_capacity(1 + values.len());
270                w.write_u8(Marker::FixArray(len as u8).into()).or(Err(SerializeError::FailedToWrite))?;
271                w
272            },
273            len if u16::max_value() as usize >= len => {
274                let mut w = Vec::with_capacity(1 + 2 + values.len());
275                w.write_u8(Marker::Array16.into()).or(Err(SerializeError::FailedToWrite))?;
276                w.write_u16::<BigEndian>(len as u16).or(Err(SerializeError::FailedToWrite))?;
277                w
278            },
279            len if u32::max_value() as usize >= len => {
280                let mut w = Vec::with_capacity(1 + 4 + values.len());
281                w.write_u8(Marker::Array32.into()).or(Err(SerializeError::FailedToWrite))?;
282                w.write_u32::<BigEndian>(len as u32).or(Err(SerializeError::FailedToWrite))?;
283                w
284            },
285            _ => Err(SerializeError::OutOfRange)?,
286        };
287        w.append(&mut values);
288        Ok(w)
289    }
290
291    fn serialize_map(v: BTreeMap<String, Self>) -> Result<Vec<u8>, SerializeError> {
292        let mut w = match v.len() {
293            len if len <= 15 => {
294                vec![Marker::FixMap(len as u8).into()]
295            },
296            len if u16::max_value() as usize >= len => {
297                let mut w = vec![Marker::Map16.into()];
298                w.write_u16::<BigEndian>(len as u16).or(Err(SerializeError::FailedToWrite))?;
299                w
300            },
301            len if u32::max_value() as usize >= len => {
302                let mut w = vec![Marker::Map32.into()];
303                w.write_u32::<BigEndian>(len as u32).or(Err(SerializeError::FailedToWrite))?;
304                w
305            },
306            _ => Err(SerializeError::OutOfRange)?,
307        };
308        for (k, v) in v {
309            w.write_all(&Self::serialize_string(k)?).or(Err(SerializeError::FailedToWrite))?;
310            w.write_all(&v.serialize()?).or(Err(SerializeError::FailedToWrite))?;
311        }
312        Ok(w)
313    }
314
315    fn serialize_extension(mut v: Extension) -> Result<Vec<u8>, SerializeError> {
316        let mut w = match v.data.len() {
317            1 => {
318                let mut w = Vec::with_capacity(1 + 1 + 1);
319                w.write_u8(Marker::FixExt1.into()).or(Err(SerializeError::FailedToWrite))?;
320                w
321            },
322            2 => {
323                let mut w = Vec::with_capacity(1 + 1 + 2);
324                w.write_u8(Marker::FixExt2.into()).or(Err(SerializeError::FailedToWrite))?;
325                w
326            },
327            4 => {
328                let mut w = Vec::with_capacity(1 + 1 + 4);
329                w.write_u8(Marker::FixExt4.into()).or(Err(SerializeError::FailedToWrite))?;
330                w
331            },
332            8 => {
333                let mut w = Vec::with_capacity(1 + 1 + 8);
334                w.write_u8(Marker::FixExt8.into()).or(Err(SerializeError::FailedToWrite))?;
335                w
336            },
337            16 => {
338                let mut w = Vec::with_capacity(1 + 1 + 16);
339                w.write_u8(Marker::FixExt16.into()).or(Err(SerializeError::FailedToWrite))?;
340                w
341            },
342            len if len <= u8::max_value() as usize => {
343                let mut w = Vec::with_capacity(1 + 1 + 1 + len);
344                w.write_u8(Marker::Ext8.into()).or(Err(SerializeError::FailedToWrite))?;
345                w.write_u8(len as u8).or(Err(SerializeError::FailedToWrite))?;
346                w
347            },
348            len if len <= u16::max_value() as usize => {
349                let mut w = Vec::with_capacity(1 + 2 + 1 + len);
350                w.write_u8(Marker::Ext16.into()).or(Err(SerializeError::FailedToWrite))?;
351                w.write_u16::<BigEndian>(len as u16).or(Err(SerializeError::FailedToWrite))?;
352                w
353            },
354            len if len <= u32::max_value() as usize => {
355                let mut w = Vec::with_capacity(1 + 4 + 1 + len);
356                w.write_u8(Marker::Ext32.into()).or(Err(SerializeError::FailedToWrite))?;
357                w.write_u32::<BigEndian>(len as u32).or(Err(SerializeError::FailedToWrite))?;
358                w
359            },
360            _ => Err(SerializeError::OutOfRange)?,
361        };
362        w.write_i8(v.t).or(Err(SerializeError::FailedToWrite))?;
363        w.append(&mut v.data);
364        Ok(w)
365    }
366
367    fn serialize_timestamp(v: DateTime<Utc>) -> Result<Vec<u8>, SerializeError> {
368        if v.timestamp() >> 34 == 0 {
369            let value = (u64::from(v.timestamp_subsec_nanos()) << 34) | (v.timestamp() as u64);
370            if value & 0xff_ff_ff_ff_00_00_00_00 == 0 {
371                let mut w = Vec::with_capacity(1 + 1 + 4);
372                w.write_u8(Marker::FixExt4.into()).or(Err(SerializeError::FailedToWrite))?;
373                w.write_i8(-1).or(Err(SerializeError::FailedToWrite))?;
374                w.write_u32::<BigEndian>(value as u32).or(Err(SerializeError::FailedToWrite))?;
375                Ok(w)
376            } else {
377                let mut w = Vec::with_capacity(1 + 1 + 8);
378                w.write_u8(Marker::FixExt8.into()).or(Err(SerializeError::FailedToWrite))?;
379                w.write_i8(-1).or(Err(SerializeError::FailedToWrite))?;
380                w.write_u64::<BigEndian>(value).or(Err(SerializeError::FailedToWrite))?;
381                Ok(w)
382            }
383        } else {
384            let mut w = Vec::with_capacity(1 + 1 + 1 + 4 + 8);
385            w.write_u8(Marker::Ext8.into()).or(Err(SerializeError::FailedToWrite))?;
386            w.write_u8(12).or(Err(SerializeError::FailedToWrite))?;
387            w.write_i8(-1).or(Err(SerializeError::FailedToWrite))?;
388            w.write_u32::<BigEndian>(v.timestamp_subsec_nanos() as u32).or(Err(SerializeError::FailedToWrite))?;
389            w.write_i64::<BigEndian>(v.timestamp()).or(Err(SerializeError::FailedToWrite))?;
390            Ok(w)
391        }
392    }
393}