rmp_serde/
lib.rs

1#![doc = include_str!("../README.md")]
2#![forbid(unsafe_code)]
3#![warn(missing_debug_implementations, missing_docs)]
4
5use std::fmt::{self, Display, Formatter};
6use std::str::{self, Utf8Error};
7
8use serde::de;
9use serde::{Deserialize, Serialize};
10
11#[allow(deprecated)]
12pub use crate::decode::from_read_ref;
13pub use crate::decode::{from_read, Deserializer};
14pub use crate::encode::{to_vec, to_vec_named, Serializer};
15
16pub use crate::decode::from_slice;
17
18mod bytes;
19pub mod config;
20pub mod decode;
21pub mod encode;
22
23/// Hack used to serialize MessagePack Extension types.
24///
25/// A special `ExtStruct` type is used to represent
26/// extension types. This struct is renamed in serde.
27///
28/// Name of Serde newtype struct to Represent Msgpack's Ext
29/// Msgpack Ext: `Ext(tag, binary)`
30/// Serde data model: `_ExtStruct((tag, binary))`
31///
32/// Example Serde impl for custom type:
33///
34/// ```ignore
35/// #[derive(Debug, PartialEq, Serialize, Deserialize)]
36/// #[serde(rename = "_ExtStruct")]
37/// struct ExtStruct((i8, serde_bytes::ByteBuf));
38///
39/// test_round(ExtStruct((2, serde_bytes::ByteBuf::from(vec![5]))),
40///            Value::Ext(2, vec![5]));
41/// ```
42pub const MSGPACK_EXT_STRUCT_NAME: &str = "_ExtStruct";
43
44/// Helper that allows both to encode and decode strings no matter whether they contain valid or
45/// invalid UTF-8.
46///
47/// Regardless of validity the UTF-8 content this type will always be serialized as a string.
48#[derive(Clone, Debug, PartialEq)]
49#[doc(hidden)]
50pub struct Raw {
51    s: Result<String, (Vec<u8>, Utf8Error)>,
52}
53
54impl Raw {
55    /// Constructs a new `Raw` from the UTF-8 string.
56    #[inline]
57    #[must_use]
58    pub fn new(v: String) -> Self {
59        Self { s: Ok(v) }
60    }
61
62    /// DO NOT USE. See <https://github.com/3Hren/msgpack-rust/issues/305>
63    #[deprecated(note = "This feature has been removed")]
64    #[must_use]
65    pub fn from_utf8(v: Vec<u8>) -> Self {
66        match String::from_utf8(v) {
67            Ok(v) => Raw::new(v),
68            Err(err) => {
69                let e = err.utf8_error();
70                Self {
71                    s: Err((err.into_bytes(), e)),
72                }
73            }
74        }
75    }
76
77    /// Returns `true` if the raw is valid UTF-8.
78    #[inline]
79    #[must_use]
80    pub fn is_str(&self) -> bool {
81        self.s.is_ok()
82    }
83
84    /// Returns `true` if the raw contains invalid UTF-8 sequence.
85    #[inline]
86    #[must_use]
87    pub fn is_err(&self) -> bool {
88        self.s.is_err()
89    }
90
91    /// Returns the string reference if the raw is valid UTF-8, or else `None`.
92    #[inline]
93    #[must_use]
94    pub fn as_str(&self) -> Option<&str> {
95        match self.s {
96            Ok(ref s) => Some(s.as_str()),
97            Err(..) => None,
98        }
99    }
100
101    /// Returns the underlying `Utf8Error` if the raw contains invalid UTF-8 sequence, or
102    /// else `None`.
103    #[inline]
104    #[must_use]
105    pub fn as_err(&self) -> Option<&Utf8Error> {
106        match self.s {
107            Ok(..) => None,
108            Err((_, ref err)) => Some(err),
109        }
110    }
111
112    /// Returns a byte slice of this raw's contents.
113    #[inline]
114    #[must_use]
115    pub fn as_bytes(&self) -> &[u8] {
116        match self.s {
117            Ok(ref s) => s.as_bytes(),
118            Err(ref err) => &err.0[..],
119        }
120    }
121
122    /// Consumes this object, yielding the string if the raw is valid UTF-8, or else `None`.
123    #[inline]
124    #[must_use]
125    pub fn into_str(self) -> Option<String> {
126        self.s.ok()
127    }
128
129    /// Converts a `Raw` into a byte vector.
130    #[inline]
131    #[must_use]
132    pub fn into_bytes(self) -> Vec<u8> {
133        match self.s {
134            Ok(s) => s.into_bytes(),
135            Err(err) => err.0,
136        }
137    }
138}
139
140impl Serialize for Raw {
141    fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
142    where
143        S: serde::Serializer,
144    {
145        match self.s {
146            Ok(ref s) => se.serialize_str(s),
147            Err((ref b, ..)) => se.serialize_bytes(b),
148        }
149    }
150}
151
152struct RawVisitor;
153
154impl<'de> de::Visitor<'de> for RawVisitor {
155    type Value = Raw;
156
157    #[cold]
158    fn expecting(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
159        "string or bytes".fmt(fmt)
160    }
161
162    #[inline]
163    fn visit_string<E>(self, v: String) -> Result<Self::Value, E> {
164        Ok(Raw { s: Ok(v) })
165    }
166
167    #[inline]
168    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
169        where E: de::Error
170    {
171        Ok(Raw { s: Ok(v.into()) })
172    }
173
174    #[inline]
175    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
176        where E: de::Error
177    {
178        let s = match str::from_utf8(v) {
179            Ok(s) => Ok(s.into()),
180            Err(err) => Err((v.into(), err)),
181        };
182
183        Ok(Raw { s })
184    }
185
186    #[inline]
187    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
188        where E: de::Error
189    {
190        let s = match String::from_utf8(v) {
191            Ok(s) => Ok(s),
192            Err(err) => {
193                let e = err.utf8_error();
194                Err((err.into_bytes(), e))
195            }
196        };
197
198        Ok(Raw { s })
199    }
200}
201
202impl<'de> Deserialize<'de> for Raw {
203    #[inline]
204    fn deserialize<D>(de: D) -> Result<Self, D::Error>
205        where D: de::Deserializer<'de>
206    {
207        de.deserialize_any(RawVisitor)
208    }
209}
210
211/// Helper that allows both to encode and decode strings no matter whether they contain valid or
212/// invalid UTF-8.
213///
214/// Regardless of validity the UTF-8 content this type will always be serialized as a string.
215#[derive(Clone, Copy, Debug, PartialEq)]
216#[doc(hidden)]
217pub struct RawRef<'a> {
218    s: Result<&'a str, (&'a [u8], Utf8Error)>,
219}
220
221impl<'a> RawRef<'a> {
222    /// Constructs a new `RawRef` from the UTF-8 string.
223    #[inline]
224    #[must_use]
225    pub fn new(v: &'a str) -> Self {
226        Self { s: Ok(v) }
227    }
228
229    #[deprecated(note = "This feature has been removed")]
230    #[must_use]
231    pub fn from_utf8(v: &'a [u8]) -> Self {
232        match str::from_utf8(v) {
233            Ok(v) => RawRef::new(v),
234            Err(err) => {
235                Self {
236                    s: Err((v, err))
237                }
238            }
239        }
240    }
241
242    /// Returns `true` if the raw is valid UTF-8.
243    #[inline]
244    #[must_use]
245    pub fn is_str(&self) -> bool {
246        self.s.is_ok()
247    }
248
249    /// Returns `true` if the raw contains invalid UTF-8 sequence.
250    #[inline]
251    #[must_use]
252    pub fn is_err(&self) -> bool {
253        self.s.is_err()
254    }
255
256    /// Returns the string reference if the raw is valid UTF-8, or else `None`.
257    #[inline]
258    #[must_use]
259    pub fn as_str(&self) -> Option<&str> {
260        match self.s {
261            Ok(s) => Some(s),
262            Err(..) => None,
263        }
264    }
265
266    /// Returns the underlying `Utf8Error` if the raw contains invalid UTF-8 sequence, or
267    /// else `None`.
268    #[inline]
269    #[must_use]
270    pub fn as_err(&self) -> Option<&Utf8Error> {
271        match self.s {
272            Ok(..) => None,
273            Err((_, ref err)) => Some(err),
274        }
275    }
276
277    /// Returns a byte slice of this raw's contents.
278    #[inline]
279    #[must_use]
280    pub fn as_bytes(&self) -> &[u8] {
281        match self.s {
282            Ok(s) => s.as_bytes(),
283            Err((bytes, _err)) => bytes,
284        }
285    }
286}
287
288impl<'a> Serialize for RawRef<'a> {
289    fn serialize<S>(&self, se: S) -> Result<S::Ok, S::Error>
290    where
291        S: serde::Serializer,
292    {
293        match self.s {
294            Ok(s) => se.serialize_str(s),
295            Err((b, ..)) => se.serialize_bytes(b),
296        }
297    }
298}
299
300struct RawRefVisitor;
301
302impl<'de> de::Visitor<'de> for RawRefVisitor {
303    type Value = RawRef<'de>;
304
305    #[cold]
306    fn expecting(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
307        "string or bytes".fmt(fmt)
308    }
309
310    #[inline]
311    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
312        where E: de::Error
313    {
314        Ok(RawRef { s: Ok(v) })
315    }
316
317    #[inline]
318    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
319        where E: de::Error
320    {
321        let s = match str::from_utf8(v) {
322            Ok(s) => Ok(s),
323            Err(err) => Err((v, err)),
324        };
325
326        Ok(RawRef { s })
327    }
328}
329
330impl<'de> Deserialize<'de> for RawRef<'de> {
331    #[inline]
332    fn deserialize<D>(de: D) -> Result<Self, D::Error>
333        where D: de::Deserializer<'de>
334    {
335        de.deserialize_any(RawRefVisitor)
336    }
337}