Coverage Report

Created: 2026-07-13 08:11

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