picodata_rmp_serde/
lib.rs

1//! This crate connects Rust MessagePack library with [`serde`][serde] providing an ability to
2//! easily serialize and deserialize both Rust built-in types, the standard library and custom data
3//! structures.
4//!
5//! ## Motivating example
6//!
7//! ```
8//! let buf = rmp_serde::to_vec(&(42, "the Answer")).unwrap();
9//!
10//! assert_eq!(
11//!     vec![0x92, 0x2a, 0xaa, 0x74, 0x68, 0x65, 0x20, 0x41, 0x6e, 0x73, 0x77, 0x65, 0x72],
12//!     buf
13//! );
14//!
15//! assert_eq!((42, "the Answer"), rmp_serde::from_read_ref(&buf).unwrap());
16//! ```
17//!
18//! # Type-based Serialization and Deserialization
19//!
20//! Serde provides a mechanism for low boilerplate serialization & deserialization of values to and
21//! from MessagePack via the serialization API.
22//!
23//! To be able to serialize a piece of data, it must implement the `serde::Serialize` trait. To be
24//! able to deserialize a piece of data, it must implement the `serde::Deserialize` trait. Serde
25//! provides an annotation to automatically generate the code for these
26//! traits: `#[derive(Serialize, Deserialize)]`.
27//!
28//! # Examples
29//!
30//! ```
31//! extern crate serde;
32//! #[macro_use]
33//! extern crate serde_derive;
34//! extern crate rmp_serde as rmps;
35//!
36//! use std::collections::HashMap;
37//! use serde::{Deserialize, Serialize};
38//! use rmps::{Deserializer, Serializer};
39//!
40//! #[derive(Debug, PartialEq, Deserialize, Serialize)]
41//! struct Human {
42//!     age: u32,
43//!     name: String,
44//! }
45//!
46//! fn main() {
47//!     let mut buf = Vec::new();
48//!     let val = Human {
49//!         age: 42,
50//!         name: "John".into(),
51//!     };
52//!
53//!     val.serialize(&mut Serializer::new(&mut buf)).unwrap();
54//! }
55//! ```
56//!
57//! [serde]: https://serde.rs/
58
59#![warn(missing_debug_implementations, missing_docs)]
60
61#[macro_use]
62extern crate serde;
63
64use std::fmt::{self, Display, Formatter};
65use std::mem;
66use std::str::{self, Utf8Error};
67
68use serde::de;
69use serde::{Deserialize, Serialize};
70
71pub use crate::decode::{from_read, from_read_ref, Deserializer};
72pub use crate::encode::{to_vec, to_vec_named, Serializer};
73
74pub use crate::decode::from_slice;
75
76pub mod config;
77pub mod decode;
78pub mod encode;
79
80/// Name of Serde newtype struct to Represent Msgpack's Ext
81/// Msgpack Ext: Ext(tag, binary)
82/// Serde data model: _ExtStruct((tag, binary))
83/// Example Serde impl for custom type:
84///
85/// ```ignore
86/// #[derive(Debug, PartialEq, Serialize, Deserialize)]
87/// #[serde(rename = "_ExtStruct")]
88/// struct ExtStruct((i8, serde_bytes::ByteBuf));
89///
90/// test_round(ExtStruct((2, serde_bytes::ByteBuf::from(vec![5]))),
91///            Value::Ext(2, vec![5]));
92/// ```
93pub const MSGPACK_EXT_STRUCT_NAME: &str = "_ExtStruct";
94
95/// Helper that allows both to encode and decode strings no matter whether they contain valid or
96/// invalid UTF-8.
97///
98/// Regardless of validity the UTF-8 content this type will always be serialized as a string.
99#[derive(Clone, Debug, PartialEq)]
100pub struct Raw {
101    s: Result<String, (Vec<u8>, Utf8Error)>,
102}
103
104impl Raw {
105    /// Constructs a new `Raw` from the UTF-8 string.
106    #[inline]
107    pub fn new(v: String) -> Self {
108        Self { s: Ok(v) }
109    }
110
111    /// Converts a vector of bytes to a `Raw`.
112    pub fn from_utf8(v: Vec<u8>) -> Self {
113        match String::from_utf8(v) {
114            Ok(v) => Raw::new(v),
115            Err(err) => {
116                let e = err.utf8_error();
117                Self {
118                    s: Err((err.into_bytes(), e)),
119                }
120            }
121        }
122    }
123
124    /// Returns `true` if the raw is valid UTF-8.
125    #[inline]
126    pub fn is_str(&self) -> bool {
127        self.s.is_ok()
128    }
129
130    /// Returns `true` if the raw contains invalid UTF-8 sequence.
131    #[inline]
132    pub fn is_err(&self) -> bool {
133        self.s.is_err()
134    }
135
136    /// Returns the string reference if the raw is valid UTF-8, or else `None`.
137    #[inline]
138    pub fn as_str(&self) -> Option<&str> {
139        match self.s {
140            Ok(ref s) => Some(s.as_str()),
141            Err(..) => None,
142        }
143    }
144
145    /// Returns the underlying `Utf8Error` if the raw contains invalid UTF-8 sequence, or
146    /// else `None`.
147    #[inline]
148    pub fn as_err(&self) -> Option<&Utf8Error> {
149        match self.s {
150            Ok(..) => None,
151            Err((_, ref err)) => Some(&err),
152        }
153    }
154
155    /// Returns a byte slice of this raw's contents.
156    #[inline]
157    pub fn as_bytes(&self) -> &[u8] {
158        match self.s {
159            Ok(ref s) => s.as_bytes(),
160            Err(ref err) => &err.0[..],
161        }
162    }
163
164    /// Consumes this object, yielding the string if the raw is valid UTF-8, or else `None`.
165    #[inline]
166    pub fn into_str(self) -> Option<String> {
167        self.s.ok()
168    }
169
170    /// Converts a `Raw` into a byte vector.
171    #[inline]
172    pub fn into_bytes(self) -> Vec<u8> {
173        match self.s {
174            Ok(s) => s.into_bytes(),
175            Err(err) => err.0,
176        }
177    }
178}
179
180impl Serialize for Raw {
181    fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
182    where
183        S: serde::Serializer
184    {
185        let s = match self.s {
186            Ok(ref s) => s.as_str(),
187            Err((ref b, ..)) => unsafe { mem::transmute(&b[..]) },
188        };
189
190        se.serialize_str(s)
191    }
192}
193
194struct RawVisitor;
195
196impl<'de> de::Visitor<'de> for RawVisitor {
197    type Value = Raw;
198
199    #[cold]
200    fn expecting(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
201        "string or bytes".fmt(fmt)
202    }
203
204    #[inline]
205    fn visit_string<E>(self, v: String) -> Result<Self::Value, E> {
206        Ok(Raw { s: Ok(v) })
207    }
208
209    #[inline]
210    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
211        where E: de::Error
212    {
213        Ok(Raw { s: Ok(v.into()) })
214    }
215
216    #[inline]
217    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
218        where E: de::Error
219    {
220        let s = match str::from_utf8(v) {
221            Ok(s) => Ok(s.into()),
222            Err(err) => Err((v.into(), err)),
223        };
224
225        Ok(Raw { s })
226    }
227
228    #[inline]
229    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
230        where E: de::Error
231    {
232        let s = match String::from_utf8(v) {
233            Ok(s) => Ok(s),
234            Err(err) => {
235                let e = err.utf8_error();
236                Err((err.into_bytes(), e))
237            }
238        };
239
240        Ok(Raw { s })
241    }
242}
243
244impl<'de> Deserialize<'de> for Raw {
245    #[inline]
246    fn deserialize<D>(de: D) -> Result<Self, D::Error>
247        where D: de::Deserializer<'de>
248    {
249        de.deserialize_any(RawVisitor)
250    }
251}
252
253/// Helper that allows both to encode and decode strings no matter whether they contain valid or
254/// invalid UTF-8.
255///
256/// Regardless of validity the UTF-8 content this type will always be serialized as a string.
257#[derive(Clone, Copy, Debug, PartialEq)]
258pub struct RawRef<'a> {
259    s: Result<&'a str, (&'a [u8], Utf8Error)>,
260}
261
262impl<'a> RawRef<'a> {
263    /// Constructs a new `RawRef` from the UTF-8 string.
264    #[inline]
265    pub fn new(v: &'a str) -> Self {
266        Self { s: Ok(v) }
267    }
268
269    /// Converts a vector of bytes to a `RawRef`.
270    pub fn from_utf8(v: &'a [u8]) -> Self {
271        match str::from_utf8(v) {
272            Ok(v) => RawRef::new(v),
273            Err(err) => {
274                Self {
275                    s: Err((v, err))
276                }
277            }
278        }
279    }
280
281    /// Returns `true` if the raw is valid UTF-8.
282    #[inline]
283    pub fn is_str(&self) -> bool {
284        self.s.is_ok()
285    }
286
287    /// Returns `true` if the raw contains invalid UTF-8 sequence.
288    #[inline]
289    pub fn is_err(&self) -> bool {
290        self.s.is_err()
291    }
292
293    /// Returns the string reference if the raw is valid UTF-8, or else `None`.
294    #[inline]
295    pub fn as_str(&self) -> Option<&str> {
296        match self.s {
297            Ok(ref s) => Some(s),
298            Err(..) => None,
299        }
300    }
301
302    /// Returns the underlying `Utf8Error` if the raw contains invalid UTF-8 sequence, or
303    /// else `None`.
304    #[inline]
305    pub fn as_err(&self) -> Option<&Utf8Error> {
306        match self.s {
307            Ok(..) => None,
308            Err((_, ref err)) => Some(&err),
309        }
310    }
311
312    /// Returns a byte slice of this raw's contents.
313    #[inline]
314    pub fn as_bytes(&self) -> &[u8] {
315        match self.s {
316            Ok(ref s) => s.as_bytes(),
317            Err(ref err) => &err.0[..],
318        }
319    }
320}
321
322impl<'a> Serialize for RawRef<'a> {
323    fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
324    where
325        S: serde::Serializer,
326    {
327        let s = match self.s {
328            Ok(ref s) => s,
329            Err((ref b, ..)) => unsafe { mem::transmute(b) },
330        };
331
332        se.serialize_str(s)
333    }
334}
335
336struct RawRefVisitor;
337
338impl<'de> de::Visitor<'de> for RawRefVisitor {
339    type Value = RawRef<'de>;
340
341    #[cold]
342    fn expecting(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
343        "string or bytes".fmt(fmt)
344    }
345
346    #[inline]
347    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
348        where E: de::Error
349    {
350        Ok(RawRef { s: Ok(v) })
351    }
352
353    #[inline]
354    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
355        where E: de::Error
356    {
357        let s = match str::from_utf8(v) {
358            Ok(s) => Ok(s),
359            Err(err) => Err((v, err)),
360        };
361
362        Ok(RawRef { s })
363    }
364}
365
366impl<'de> Deserialize<'de> for RawRef<'de> {
367    #[inline]
368    fn deserialize<D>(de: D) -> Result<Self, D::Error>
369        where D: de::Deserializer<'de>
370    {
371        de.deserialize_any(RawRefVisitor)
372    }
373}