/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 | | } |