simple_serde/
lib.rs

1//! # Simple Serde
2//! Simple serde is as its said, a simplified implementation of multiple repositories for
3//! serialization and deserialization.
4//!
5//! In Short the goal is to have a single tool for serialization and deserialization, with a common
6//! interface.
7//!
8//! # Usage
9//! Simple Serde uses `.encode` and `.decode` for encoding and decoding. Decode can be done on any
10//! `Vec<u8>` or `&[u8]` this allows for the cleanest implementation.
11//! The same goes for anything that needs to be serialized/encoded. Any type that implements the
12//! `#[derive(Serialize)]` can easily be encoded using `.encode`
13//!
14//! ## Encode/Decode
15//! `.encode` and `.decode` both takes a `ContentType` which defines what you are encoding/decoding
16//! from/to.
17//! an example would be `[some Vec<u8>].decode("bson")` or `my_struct.encode("bson")`.
18//! This is possible as `ContentType` implements the `TryFrom` trait for `&str`, `String`.
19//! In case the implementation is unable to decode what type you are trying to encode/decode from/to
20//! an `Err` result with `Error::UnknownContentTypeMatchFromStr` will be returned from the
21//! encoder/decoder
22//!
23//! Anything coming out of the encoder will be of type `Vec<u8>` further the `Vec<u8>` is wrapped in
24//! a struct called `Encoded` this allow for further simplifications on implementation like,
25//! `TryToString` which will automatically try to convert `Encoded` to a `String`, in addition
26//! `Encoded` had implemented the `Deref` and `DerefMut` traits to make it easier to gain access to
27//! encapsulated data.
28//!
29//! ## Supported formats
30//! - Bson
31//! - Cbor
32//! - FlexBuffers
33//! - Json
34//! - Json5
35//! - Lexpr
36//! - MessagePack
37//! - Pickle
38//! - Postcard
39//! - Ron
40//! - Toml
41//! - Url
42//! - Yaml
43//! - Xml (Awaiting serde-xml-rs v. >0.51)
44//!
45//! further all string definitions of `ContentType` is case insensitive, and has an alternate
46//! - `application/[format]`
47//! - `application/x-[format]`
48//!
49//! ## Serialization/Encode example
50//! ```rust
51//! use std::ops::Deref;
52//! use serde::Serialize;
53//! #[macro_use]
54//! use serde_derive;
55//! use simple_serde::{Encoded, SimpleEncoder, TryToString};
56//!
57//! #[derive(Serialize)]
58//! struct Foo {
59//!     bar: String,
60//! }
61//!
62//! let my_foo = Foo {
63//!   bar: "foobar".to_string(),
64//! };
65//!
66//! let encoded: Encoded = my_foo
67//!   .encode("yaml")
68//!   .expect("Should have been encoded in yaml");
69//!
70//! assert_eq!(
71//!     &vec![98, 97, 114, 58, 32, 102, 111, 111, 98, 97, 114, 10],
72//!     encoded.deref()
73//! );
74//! assert_eq!(r#"bar: foobar
75//! "#, encoded.try_to_string().unwrap())
76//! ```
77//! ## Deserialization/Decode example
78//! ```rust
79//! use std::ops::Deref;
80//! use serde::Deserialize;
81//! #[macro_use]
82//! use serde_derive;
83//! use simple_serde::{Decoded, SimpleDecoder};
84//!
85//! #[derive(Deserialize, Debug, PartialEq)]
86//! struct Foo {
87//!     bar: String,
88//! }
89//!
90//! let my_foo = Foo {
91//!   bar: "foobar".to_string(),
92//! };
93//!
94//! let v_u8_data = &vec![45, 45, 45, 10, 98, 97, 114, 58, 32, 102, 111, 111, 98, 97, 114, 10];
95//! let string_data = r#"---
96//! bar: foobar
97//! "#;
98//!
99//! let decoded_from_v_u8: Decoded<Foo> = v_u8_data.decode("yaml").expect("Should have decoded the Vec<u8>");
100//! let decoded_from_string: Decoded<Foo> = string_data.decode("yaml").expect("Should have decoded the String");
101//!
102//! assert_eq!(
103//!     Foo{bar: "foobar".to_string()},
104//!     decoded_from_v_u8.into()
105//! );
106//! assert_eq!(
107//!     Foo{bar: "foobar".to_string()},
108//!     decoded_from_string.into()
109//! );
110//! ```
111
112#[cfg(feature = "bson")]
113extern crate bson;
114#[cfg(feature = "flexbuffers")]
115extern crate flexbuffers;
116#[cfg(feature = "actix-http")]
117extern crate http;
118#[cfg(feature = "json5")]
119extern crate json5;
120#[cfg(feature = "postcard")]
121extern crate postcard;
122#[cfg(feature = "messagepack")]
123extern crate rmp_serde;
124#[cfg(feature = "ron")]
125extern crate ron;
126extern crate serde;
127#[cfg(feature = "cbor")]
128extern crate serde_cbor;
129extern crate serde_derive;
130#[cfg(feature = "json")]
131extern crate serde_json;
132#[cfg(feature = "lexpr")]
133extern crate serde_lexpr;
134#[cfg(feature = "pickle")]
135extern crate serde_pickle as pickle;
136#[cfg(feature = "query-string")]
137extern crate serde_qs;
138#[cfg(feature = "accept-limited-xml-serialize")]
139extern crate serde_xml_rs;
140#[cfg(feature = "yaml")]
141extern crate serde_yaml;
142
143use core::str::from_utf8;
144
145pub mod prelude {
146    #[cfg(feature = "bson")]
147    pub extern crate bson;
148    #[cfg(feature = "flexbuffers")]
149    pub extern crate flexbuffers;
150    #[cfg(feature = "json5")]
151    pub extern crate json5;
152    #[cfg(feature = "postcard")]
153    pub extern crate postcard;
154    #[cfg(feature = "messagepack")]
155    pub extern crate rmp_serde as messagepack;
156    #[cfg(feature = "ron")]
157    pub extern crate ron;
158    #[cfg(feature = "cbor")]
159    pub extern crate serde_cbor as cbor;
160    pub extern crate serde_derive;
161    #[cfg(feature = "json")]
162    pub extern crate serde_json as json;
163    #[cfg(feature = "lexpr")]
164    pub extern crate serde_lexpr as lexpr;
165    #[cfg(feature = "pickle")]
166    pub extern crate serde_pickle as pickle;
167    #[cfg(feature = "query-string")]
168    pub extern crate serde_qs as qs;
169    #[cfg(feature = "accept-limited-xml-serialize")]
170    pub extern crate serde_xml_rs as xml;
171    #[cfg(feature = "yaml")]
172    pub extern crate serde_yaml as yaml;
173}
174
175#[cfg(feature = "actix-http")]
176use crate::Error::InvalidHeaderValue;
177#[cfg(feature = "actix-http")]
178use actix_http::header::TryIntoHeaderValue;
179use derive_more::Display;
180#[cfg(feature = "actix-http")]
181use http::{header::ToStrError, HeaderValue};
182#[cfg(feature = "ron")]
183use ron::de::SpannedError;
184use serde::de::DeserializeOwned;
185use serde::Serialize;
186use std::convert::{Infallible, Into, TryFrom, TryInto};
187use std::ops::{Deref, DerefMut};
188use std::str::Utf8Error;
189
190pub type Result<T> = std::result::Result<T, Error>;
191
192#[derive(PartialEq, Eq, Debug)]
193pub enum ContentType {
194    #[cfg(feature = "bson")]
195    Bson,
196    #[cfg(feature = "cbor")]
197    Cbor,
198    #[cfg(feature = "flexbuffers")]
199    FlexBuffers,
200    #[cfg(feature = "json")]
201    Json,
202    #[cfg(feature = "json5")]
203    Json5,
204    #[cfg(feature = "lexpr")]
205    Lexpr,
206    #[cfg(feature = "messagepack")]
207    MessagePack,
208    #[cfg(feature = "pickle")]
209    Pickle,
210    #[cfg(feature = "postcard")]
211    Postcard,
212    #[cfg(feature = "ron")]
213    Ron,
214    #[cfg(feature = "toml")]
215    Toml,
216    #[cfg(feature = "query-string")]
217    QueryString,
218    #[cfg(feature = "yaml")]
219    Yaml,
220    #[cfg(feature = "accept-limited-xml-serialize")]
221    Xml,
222}
223
224impl TryFrom<&str> for ContentType {
225    type Error = crate::Error;
226
227    fn try_from(s: &str) -> std::result::Result<ContentType, Self::Error> {
228        #[allow(unreachable_patterns)]
229        match s.to_lowercase().as_str() {
230            #[cfg(feature = "bson")]
231            "bson" => Ok(ContentType::Bson),
232            #[cfg(feature = "bson")]
233            "application/bson" => Ok(ContentType::Bson),
234            #[cfg(feature = "bson")]
235            "application/x-bson" => Ok(ContentType::Bson),
236            #[cfg(feature = "cbor")]
237            "cbor" => Ok(ContentType::Cbor),
238            #[cfg(feature = "cbor")]
239            "application/cbor" => Ok(ContentType::Cbor),
240            #[cfg(feature = "cbor")]
241            "application/x-cbor" => Ok(ContentType::Cbor),
242            #[cfg(feature = "flexbuffers")]
243            "flexbuffers" => Ok(ContentType::FlexBuffers),
244            #[cfg(feature = "flexbuffers")]
245            "application/flexbuffers" => Ok(ContentType::FlexBuffers),
246            #[cfg(feature = "flexbuffers")]
247            "application/x-flexbuffers" => Ok(ContentType::FlexBuffers),
248            #[cfg(feature = "json")]
249            "json" => Ok(ContentType::Json),
250            #[cfg(feature = "json")]
251            "application/json" => Ok(ContentType::Json),
252            #[cfg(feature = "json")]
253            "application/x-json" => Ok(ContentType::Json),
254            #[cfg(feature = "json5")]
255            "json5" => Ok(ContentType::Json5),
256            #[cfg(feature = "json5")]
257            "application/json5" => Ok(ContentType::Json5),
258            #[cfg(feature = "json5")]
259            "application/x-json5" => Ok(ContentType::Json5),
260            #[cfg(feature = "lexpr")]
261            "lexpr" => Ok(ContentType::Lexpr),
262            #[cfg(feature = "lexpr")]
263            "application/lexpr" => Ok(ContentType::Lexpr),
264            #[cfg(feature = "lexpr")]
265            "application/x-lexpr" => Ok(ContentType::Lexpr),
266            #[cfg(feature = "messagepack")]
267            "messagepack" => Ok(ContentType::MessagePack),
268            #[cfg(feature = "messagepack")]
269            "application/messagepack" => Ok(ContentType::MessagePack),
270            #[cfg(feature = "messagepack")]
271            "application/x-messagepack" => Ok(ContentType::MessagePack),
272            #[cfg(feature = "pickle")]
273            "pickle" => Ok(ContentType::Pickle),
274            #[cfg(feature = "pickle")]
275            "application/pickle" => Ok(ContentType::Pickle),
276            #[cfg(feature = "pickle")]
277            "application/x-pickle" => Ok(ContentType::Pickle),
278            #[cfg(feature = "postcard")]
279            "postcard" => Ok(ContentType::Postcard),
280            #[cfg(feature = "postcard")]
281            "application/postcard" => Ok(ContentType::Postcard),
282            #[cfg(feature = "postcard")]
283            "application/x-postcard" => Ok(ContentType::Postcard),
284            #[cfg(feature = "ron")]
285            "ron" => Ok(ContentType::Ron),
286            #[cfg(feature = "ron")]
287            "application/ron" => Ok(ContentType::Ron),
288            #[cfg(feature = "ron")]
289            "application/x-ron" => Ok(ContentType::Ron),
290            #[cfg(feature = "toml")]
291            "toml" => Ok(ContentType::Toml),
292            #[cfg(feature = "toml")]
293            "application/toml" => Ok(ContentType::Toml),
294            #[cfg(feature = "toml")]
295            "application/x-toml" => Ok(ContentType::Toml),
296            #[cfg(feature = "query-string")]
297            "querystring" => Ok(ContentType::QueryString),
298            #[cfg(feature = "query-string")]
299            "application/querystring" => Ok(ContentType::QueryString),
300            #[cfg(feature = "query-string")]
301            "application/x-querystring" => Ok(ContentType::QueryString),
302            #[cfg(feature = "yaml")]
303            "yaml" => Ok(ContentType::Yaml),
304            #[cfg(feature = "yaml")]
305            "application/yaml" => Ok(ContentType::Yaml),
306            #[cfg(feature = "yaml")]
307            "application/x-yaml" => Ok(ContentType::Yaml),
308            #[cfg(feature = "accept-limited-xml-serialize")]
309            "xml" => Ok(ContentType::Xml),
310            #[cfg(feature = "accept-limited-xml-serialize")]
311            "application/xml" => Ok(ContentType::Xml),
312            #[cfg(feature = "accept-limited-xml-serialize")]
313            "application/x-xml" => Ok(ContentType::Xml),
314            _ => Err(Error::UnknownContentTypeMatchFromStr(s.to_string())),
315        }
316    }
317}
318
319impl TryFrom<String> for ContentType {
320    type Error = crate::Error;
321
322    fn try_from(s: String) -> std::result::Result<ContentType, Self::Error> {
323        Self::try_from(s.as_str())
324    }
325}
326
327impl TryFrom<&String> for ContentType {
328    type Error = crate::Error;
329
330    fn try_from(s: &String) -> std::result::Result<ContentType, Self::Error> {
331        Self::try_from(s.as_str())
332    }
333}
334
335impl TryFrom<&ContentType> for ContentType {
336    type Error = crate::Error;
337
338    fn try_from(h: &ContentType) -> std::result::Result<ContentType, Self::Error> {
339        match h {
340            #[cfg(feature = "bson")]
341            Self::Bson => Ok(Self::Bson),
342            #[cfg(feature = "cbor")]
343            Self::Cbor => Ok(Self::Cbor),
344            #[cfg(feature = "flexbuffers")]
345            Self::FlexBuffers => Ok(Self::FlexBuffers),
346            #[cfg(feature = "json")]
347            Self::Json => Ok(Self::Json),
348            #[cfg(feature = "json5")]
349            Self::Json5 => Ok(Self::Json5),
350            #[cfg(feature = "lexpr")]
351            Self::Lexpr => Ok(Self::Lexpr),
352            #[cfg(feature = "messagepack")]
353            Self::MessagePack => Ok(Self::MessagePack),
354            #[cfg(feature = "pickle")]
355            Self::Pickle => Ok(Self::Pickle),
356            #[cfg(feature = "postcard")]
357            Self::Postcard => Ok(Self::Postcard),
358            #[cfg(feature = "ron")]
359            Self::Ron => Ok(Self::Ron),
360            #[cfg(feature = "toml")]
361            Self::Toml => Ok(Self::Toml),
362            #[cfg(feature = "query-string")]
363            Self::QueryString => Ok(Self::QueryString),
364            #[cfg(feature = "yaml")]
365            Self::Yaml => Ok(Self::Yaml),
366            #[cfg(feature = "accept-limited-xml-serialize")]
367            Self::Xml => Ok(Self::Xml),
368            _ => Err(Self::Error::NoSerializersDeserializersSet),
369        }
370    }
371}
372
373#[cfg(feature = "actix-http")]
374impl TryIntoHeaderValue for ContentType {
375    type Error = http::header::InvalidHeaderValue;
376
377    fn try_into_value(self) -> std::result::Result<HeaderValue, Self::Error> {
378        HeaderValue::from_str(match self {
379            #[cfg(feature = "bson")]
380            ContentType::Bson => "application/x-bson",
381            #[cfg(feature = "cbor")]
382            ContentType::Cbor => "application/x-cbor",
383            #[cfg(feature = "flexbuffers")]
384            ContentType::FlexBuffers => "application/x-flexbuffers",
385            #[cfg(feature = "json")]
386            ContentType::Json => "application/json",
387            #[cfg(feature = "json5")]
388            ContentType::Json5 => "application/json5",
389            #[cfg(feature = "lexpr")]
390            ContentType::Lexpr => "application/x-lexpr",
391            #[cfg(feature = "messagepack")]
392            ContentType::MessagePack => "application/x-messagepack",
393            #[cfg(feature = "pickle")]
394            ContentType::Pickle => "application/x-pickle",
395            #[cfg(feature = "postcard")]
396            ContentType::Postcard => "application/x-postcard",
397            #[cfg(feature = "ron")]
398            ContentType::Ron => "application/ron",
399            #[cfg(feature = "toml")]
400            ContentType::Toml => "application/toml",
401            #[cfg(feature = "query-string")]
402            ContentType::QueryString => "application/x-url",
403            #[cfg(feature = "yaml")]
404            ContentType::Yaml => "application/yaml",
405            #[cfg(feature = "accept-limited-xml-serialize")]
406            ContentType::Xml => "application/xml",
407        })
408    }
409}
410
411#[cfg(feature = "actix-http")]
412impl TryIntoHeaderValue for &ContentType {
413    type Error = http::header::InvalidHeaderValue;
414
415    fn try_into_value(self) -> std::result::Result<HeaderValue, Self::Error> {
416        HeaderValue::from_str(match self {
417            #[cfg(feature = "bson")]
418            ContentType::Bson => "application/x-bson",
419            #[cfg(feature = "cbor")]
420            ContentType::Cbor => "application/x-cbor",
421            #[cfg(feature = "flexbuffers")]
422            ContentType::FlexBuffers => "application/x-flexbuffers",
423            #[cfg(feature = "json")]
424            ContentType::Json => "application/json",
425            #[cfg(feature = "json5")]
426            ContentType::Json5 => "application/json5",
427            #[cfg(feature = "lexpr")]
428            ContentType::Lexpr => "application/x-lexpr",
429            #[cfg(feature = "messagepack")]
430            ContentType::MessagePack => "application/x-messagepack",
431            #[cfg(feature = "pickle")]
432            ContentType::Pickle => "application/x-pickle",
433            #[cfg(feature = "postcard")]
434            ContentType::Postcard => "application/x-postcard",
435            #[cfg(feature = "ron")]
436            ContentType::Ron => "application/ron",
437            #[cfg(feature = "toml")]
438            ContentType::Toml => "application/toml",
439            #[cfg(feature = "query-string")]
440            ContentType::QueryString => "application/x-url",
441            #[cfg(feature = "yaml")]
442            ContentType::Yaml => "application/yaml",
443            #[cfg(feature = "accept-limited-xml-serialize")]
444            ContentType::Xml => "application/xml",
445        })
446    }
447}
448
449#[cfg(feature = "actix-http")]
450impl TryFrom<HeaderValue> for ContentType {
451    type Error = Error;
452
453    fn try_from(h: HeaderValue) -> std::result::Result<ContentType, Self::Error> {
454        h.to_str()
455            .map_err(Error::from)
456            .and_then(ContentType::try_from)
457    }
458}
459
460#[cfg(feature = "actix-http")]
461impl TryFrom<&HeaderValue> for ContentType {
462    type Error = Error;
463
464    fn try_from(h: &HeaderValue) -> std::result::Result<ContentType, Self::Error> {
465        h.to_str()
466            .map_err(Error::from)
467            .and_then(ContentType::try_from)
468    }
469}
470
471#[derive(Debug, Display)]
472pub enum Error {
473    #[display(fmt = "Infallible - This error should have been infallible")]
474    Infallible,
475    #[display(fmt = "Converting Raw Data to UTF8 failed: {}", _0)]
476    ByteToUTF8ConversionFailure(Utf8Error),
477    #[display(fmt = "Unknown content type match from str: {}", _0)]
478    UnknownContentTypeMatchFromStr(String),
479    #[cfg(feature = "bson")]
480    #[display(fmt = "BSON encoder/decoder error: {}", _0)]
481    BsonSerializationFailure(bson::ser::Error),
482    #[cfg(feature = "bson")]
483    #[display(fmt = "BSON encode/decoder error: {}", _0)]
484    BsonDeserializationFailure(bson::de::Error),
485    #[cfg(feature = "cbor")]
486    #[display(fmt = "CBOR encoder/decoder error: {}", _0)]
487    CborFailure(serde_cbor::Error),
488    #[cfg(feature = "flexbuffers")]
489    #[display(fmt = "Flexbuffers encoder/decoder error: {}", _0)]
490    FlexBuffersSerializationFailure(flexbuffers::SerializationError),
491    #[cfg(feature = "flexbuffers")]
492    #[display(fmt = "Flexbuffers encoder/decoder error: {}", _0)]
493    FlexBuffersDeserializationFailure(flexbuffers::DeserializationError),
494    #[cfg(feature = "json")]
495    #[display(fmt = "JSON encoder/decoder error: {}", _0)]
496    JsonError(serde_json::Error),
497    #[cfg(feature = "json5")]
498    #[display(fmt = "JSON5 encoder/decoder error: {}", _0)]
499    Json5Error(json5::Error),
500    #[cfg(feature = "lexpr")]
501    #[display(fmt = "LEXPR encoder/decoder error: {}", _0)]
502    LexprError(serde_lexpr::Error),
503    #[cfg(feature = "messagepack")]
504    #[display(fmt = "MessagePack encoder/decoder error: {}", _0)]
505    MessagePackEncodeError(rmp_serde::encode::Error),
506    #[cfg(feature = "messagepack")]
507    #[display(fmt = "MessagePack encoder/decoder error: {}", _0)]
508    MessagePackDecodeError(rmp_serde::decode::Error),
509    #[cfg(feature = "pickle")]
510    #[display(fmt = "Pickle encoder/decoder error: {}", _0)]
511    PickleError(serde_pickle::Error),
512    #[cfg(feature = "postcard")]
513    #[display(fmt = "Postcard encoder/decoder error: {}", _0)]
514    PostcardError(postcard::Error),
515    #[cfg(feature = "ron")]
516    #[display(fmt = "RON encoder/decoder error: {}", _0)]
517    RonError(ron::Error),
518    #[cfg(feature = "ron")]
519    #[display(fmt = "RON decoder error: {}", _0)]
520    RonDecodeError(ron::de::SpannedError),
521    #[cfg(feature = "toml")]
522    #[display(fmt = "TOML encoder/decoder error: {}", _0)]
523    TomlSerializationFailure(toml::ser::Error),
524    #[cfg(feature = "toml")]
525    #[display(fmt = "TOML encoder/decoder error: {}", _0)]
526    TomlDeserializationFailure(toml::de::Error),
527    #[cfg(feature = "query-string")]
528    #[display(fmt = "URL encoder/decoder error: {}", _0)]
529    QueryStringEncodingFailure(serde_qs::Error),
530    #[cfg(feature = "yaml")]
531    #[display(fmt = "YAML encoder/decoder error: {}", _0)]
532    YamlError(serde_yaml::Error),
533    #[cfg(feature = "accept-limited-xml-serialize")]
534    #[display(fmt = "XML encoder/decoder error: {}", _0)]
535    XmlError(prelude::xml::Error),
536    #[display(fmt = "Type is not supported for encoding/decoding: {:?}", _0)]
537    TypeDoesNotSupportSerialization(ContentType),
538    #[cfg(feature = "actix-http")]
539    #[display(fmt = "Failed to convert `HeaderValue` to a ContentType: {}", _0)]
540    FailedConvertingHeaderValueToContentType(http::header::ToStrError),
541    #[cfg(feature = "actix-http")]
542    #[display(fmt = "Invalid Header Value found: {}", _0)]
543    InvalidHeaderValue(http::header::InvalidHeaderValue),
544    #[display(fmt = "This would only happen if no serializers/deserializers have been set")]
545    NoSerializersDeserializersSet,
546}
547
548#[cfg(feature = "actix-http")]
549impl From<http::header::InvalidHeaderValue> for Error {
550    fn from(e: http::header::InvalidHeaderValue) -> Self {
551        Self::InvalidHeaderValue(e)
552    }
553}
554
555#[cfg(feature = "actix-http")]
556impl From<http::header::ToStrError> for Error {
557    fn from(e: ToStrError) -> Self {
558        Self::FailedConvertingHeaderValueToContentType(e)
559    }
560}
561
562// Test for this from is disabled as its not possible to create the external
563// `std::convert::Infallible` object
564#[cfg(not(tarpaulin_include))]
565impl From<std::convert::Infallible> for Error {
566    fn from(_: Infallible) -> Self {
567        Error::Infallible
568    }
569}
570
571// Unable to test due to no access to object
572#[cfg(not(tarpaulin_include))]
573impl From<Utf8Error> for Error {
574    fn from(e: Utf8Error) -> Self {
575        Error::ByteToUTF8ConversionFailure(e)
576    }
577}
578
579#[cfg(feature = "bson")]
580impl From<bson::ser::Error> for Error {
581    fn from(e: bson::ser::Error) -> Self {
582        Error::BsonSerializationFailure(e)
583    }
584}
585
586#[cfg(feature = "bson")]
587impl From<bson::de::Error> for Error {
588    fn from(e: bson::de::Error) -> Self {
589        Error::BsonDeserializationFailure(e)
590    }
591}
592
593#[cfg(feature = "cbor")]
594impl From<serde_cbor::Error> for Error {
595    fn from(e: serde_cbor::Error) -> Self {
596        Error::CborFailure(e)
597    }
598}
599
600#[cfg(feature = "flexbuffers")]
601impl From<flexbuffers::SerializationError> for Error {
602    fn from(e: flexbuffers::SerializationError) -> Self {
603        Error::FlexBuffersSerializationFailure(e)
604    }
605}
606
607#[cfg(feature = "flexbuffers")]
608impl From<flexbuffers::DeserializationError> for Error {
609    fn from(e: flexbuffers::DeserializationError) -> Self {
610        Error::FlexBuffersDeserializationFailure(e)
611    }
612}
613
614#[cfg(feature = "json")]
615impl From<serde_json::Error> for Error {
616    fn from(e: serde_json::Error) -> Self {
617        Error::JsonError(e)
618    }
619}
620
621#[cfg(feature = "json5")]
622impl From<json5::Error> for Error {
623    fn from(e: json5::Error) -> Self {
624        Error::Json5Error(e)
625    }
626}
627
628#[cfg(feature = "lexpr")]
629impl From<serde_lexpr::Error> for Error {
630    fn from(e: serde_lexpr::Error) -> Self {
631        Error::LexprError(e)
632    }
633}
634
635#[cfg(feature = "messagepack")]
636impl From<rmp_serde::encode::Error> for Error {
637    fn from(e: rmp_serde::encode::Error) -> Self {
638        Error::MessagePackEncodeError(e)
639    }
640}
641
642#[cfg(feature = "messagepack")]
643impl From<rmp_serde::decode::Error> for Error {
644    fn from(e: rmp_serde::decode::Error) -> Self {
645        Error::MessagePackDecodeError(e)
646    }
647}
648
649#[cfg(feature = "pickle")]
650impl From<serde_pickle::Error> for Error {
651    fn from(e: serde_pickle::Error) -> Self {
652        Error::PickleError(e)
653    }
654}
655
656#[cfg(feature = "postcard")]
657impl From<postcard::Error> for Error {
658    fn from(e: postcard::Error) -> Self {
659        Error::PostcardError(e)
660    }
661}
662
663#[cfg(feature = "ron")]
664impl From<ron::Error> for Error {
665    fn from(e: ron::Error) -> Self {
666        Error::RonError(e)
667    }
668}
669
670#[cfg(feature = "toml")]
671impl From<toml::ser::Error> for Error {
672    fn from(e: toml::ser::Error) -> Self {
673        Error::TomlSerializationFailure(e)
674    }
675}
676
677#[cfg(feature = "toml")]
678impl From<toml::de::Error> for Error {
679    fn from(e: toml::de::Error) -> Self {
680        Error::TomlDeserializationFailure(e)
681    }
682}
683
684#[cfg(feature = "query-string")]
685impl From<serde_qs::Error> for Error {
686    fn from(e: serde_qs::Error) -> Self {
687        Error::QueryStringEncodingFailure(e)
688    }
689}
690
691#[cfg(feature = "yaml")]
692impl From<serde_yaml::Error> for Error {
693    fn from(e: serde_yaml::Error) -> Self {
694        Error::YamlError(e)
695    }
696}
697
698#[cfg(feature = "accept-limited-xml-serialize")]
699impl From<prelude::xml::Error> for Error {
700    fn from(e: prelude::xml::Error) -> Self {
701        Error::XmlError(e)
702    }
703}
704
705#[cfg(feature = "ron")]
706impl From<ron::de::SpannedError> for Error {
707    fn from(e: ron::de::SpannedError) -> Self {
708        Self::RonDecodeError(e)
709    }
710}
711
712pub trait TryToString {
713    type Error;
714    fn try_to_string(&self) -> std::result::Result<String, Self::Error>;
715}
716
717pub trait SimpleEncoder
718    where
719        Self: serde::Serialize,
720{
721    fn encode<F: TryInto<ContentType, Error=impl Into<crate::Error>>>(
722        &self,
723        content_type: F,
724    ) -> Result<Encoded>;
725}
726
727impl<T> SimpleEncoder for T
728    where
729        T: Serialize,
730{
731    fn encode<F: TryInto<ContentType, Error=impl Into<crate::Error>>>(
732        &self,
733        content_type: F,
734    ) -> Result<Encoded> {
735        #[cfg(feature = "bson")]
736            let bson = |o: &T| -> Result<Encoded> { bson::to_vec(o).try_into() };
737        #[cfg(feature = "cbor")]
738            let cbor = |o: &T| -> Result<Encoded> { serde_cbor::to_vec(o).try_into() };
739        #[cfg(feature = "flexbuffers")]
740            let flexbuffers = |o: &T| -> Result<Encoded> { flexbuffers::to_vec(o).try_into() };
741        #[cfg(feature = "json")]
742            let json = |o: &T| -> Result<Encoded> { serde_json::to_vec(o).try_into() };
743        #[cfg(feature = "json5")]
744            let json5 = |o: &T| -> Result<Encoded> { json5::to_string(o).try_into() };
745        #[cfg(feature = "lexpr")]
746            let lexpr = |o: &T| -> Result<Encoded> { serde_lexpr::to_vec(o).try_into() };
747        #[cfg(feature = "messagepack")]
748            let message_pack = |o: &T| -> Result<Encoded> { rmp_serde::to_vec(o).try_into() };
749        #[cfg(feature = "pickle")]
750            let pickle =
751            |o: &T| -> Result<Encoded> { serde_pickle::to_vec(o, Default::default()).try_into() };
752        #[cfg(feature = "postcard")]
753            let postcard = |o: &T| -> Result<Encoded> { postcard::to_allocvec(o).try_into() };
754        #[cfg(feature = "ron")]
755            let ron = |o: &T| -> Result<Encoded> { ron::to_string(o).try_into() };
756        #[cfg(feature = "toml")]
757            let toml = |o: &T| -> Result<Encoded> { toml::to_string(o).try_into() };
758        #[cfg(feature = "query-string")]
759            let querystring = |o: &T| -> Result<Encoded> { serde_qs::to_string(o).try_into() };
760        #[cfg(feature = "yaml")]
761            let yaml = |o: &T| -> Result<Encoded> { serde_yaml::to_string(o).try_into() };
762        #[cfg(feature = "accept-limited-xml-serialize")]
763            let xml = |o: &T| -> Result<Encoded> { prelude::xml::to_string(o).try_into() };
764        match content_type.try_into().map_err(|e| e.into())? {
765            #[cfg(feature = "bson")]
766            ContentType::Bson => bson(self),
767            #[cfg(feature = "cbor")]
768            ContentType::Cbor => cbor(self),
769            #[cfg(feature = "flexbuffers")]
770            ContentType::FlexBuffers => flexbuffers(self),
771            #[cfg(feature = "json")]
772            ContentType::Json => json(self),
773            #[cfg(feature = "json5")]
774            ContentType::Json5 => json5(self),
775            #[cfg(feature = "lexpr")]
776            ContentType::Lexpr => lexpr(self),
777            #[cfg(feature = "messagepack")]
778            ContentType::MessagePack => message_pack(self),
779            #[cfg(feature = "pickle")]
780            ContentType::Pickle => pickle(self),
781            #[cfg(feature = "postcard")]
782            ContentType::Postcard => postcard(self),
783            #[cfg(feature = "ron")]
784            ContentType::Ron => ron(self),
785            #[cfg(feature = "toml")]
786            ContentType::Toml => toml(self),
787            #[cfg(feature = "query-string")]
788            ContentType::QueryString => querystring(self),
789            #[cfg(feature = "yaml")]
790            ContentType::Yaml => yaml(self),
791            #[cfg(feature = "accept-limited-xml-serialize")]
792            ContentType::Xml => xml(self),
793        }
794    }
795}
796
797pub trait SimpleDecoder<T> {
798    fn decode<F: TryInto<ContentType, Error=impl Into<crate::Error>>>(
799        &self,
800        content_type: F,
801    ) -> Result<T>;
802}
803
804impl<T> SimpleDecoder<Decoded<T>> for &[u8]
805    where
806        T: DeserializeOwned,
807{
808    fn decode<F: TryInto<ContentType, Error=impl Into<crate::Error>>>(
809        &self,
810        content_type: F,
811    ) -> Result<Decoded<T>> {
812        #[cfg(feature = "bson")]
813            let bson = |o: &[u8]| -> Result<Decoded<T>> { bson::from_slice(o).try_into() };
814        #[cfg(feature = "cbor")]
815            let cbor = |o: &[u8]| -> Result<Decoded<T>> { serde_cbor::from_slice(o).try_into() };
816        #[cfg(feature = "flexbuffers")]
817            let flexbuffers =
818            |o: &[u8]| -> Result<Decoded<T>> { flexbuffers::from_slice(o).try_into() };
819        #[cfg(feature = "json")]
820            let json = |o: &[u8]| -> Result<Decoded<T>> { serde_json::from_slice(o).try_into() };
821        #[cfg(feature = "json5")]
822            let json5 = |o: &[u8]| -> Result<Decoded<T>> {
823            std::str::from_utf8(o)
824                .map_err(Error::from)
825                .and_then(|str| json5::from_str(str).try_into())
826        };
827        #[cfg(feature = "lexpr")]
828            let lexpr = |o: &[u8]| -> Result<Decoded<T>> { serde_lexpr::from_slice(o).try_into() };
829        #[cfg(feature = "messagepack")]
830            let message_pack = |o: &[u8]| -> Result<Decoded<T>> { rmp_serde::from_slice(o).try_into() };
831        #[cfg(feature = "pickle")]
832            let pickle = |o: &[u8]| -> Result<Decoded<T>> {
833            serde_pickle::from_slice(o, Default::default()).try_into()
834        };
835        #[cfg(feature = "postcard")]
836            let postcard = |o: &[u8]| -> Result<Decoded<T>> { postcard::from_bytes(o).try_into() };
837        #[cfg(feature = "ron")]
838            let ron = |o: &[u8]| -> Result<Decoded<T>> {
839            std::str::from_utf8(o)
840                .map_err(Error::from)
841                .and_then(|str| ron::from_str(str).try_into())
842        };
843        #[cfg(feature = "toml")]
844            let toml = |o: &[u8]| -> Result<Decoded<T>> { from_utf8(o).map_err(Error::from).and_then(|t| toml::from_str(t).try_into()) };
845        #[cfg(feature = "query-string")]
846            let querystring = |o: &[u8]| -> Result<Decoded<T>> { serde_qs::from_bytes(o).try_into() };
847        #[cfg(feature = "yaml")]
848            let yaml = |o: &[u8]| -> Result<Decoded<T>> { serde_yaml::from_slice(o).try_into() };
849        #[cfg(feature = "accept-limited-xml-serialize")]
850            let xml = |o: &[u8]| -> Result<Decoded<T>> {
851            std::str::from_utf8(o)
852                .map_err(Error::from)
853                .and_then(|str| prelude::xml::de::from_str(str).try_into())
854        };
855        match content_type.try_into().map_err(|e| e.into())? {
856            #[cfg(feature = "bson")]
857            ContentType::Bson => bson(self),
858            #[cfg(feature = "cbor")]
859            ContentType::Cbor => cbor(self),
860            #[cfg(feature = "flexbuffers")]
861            ContentType::FlexBuffers => flexbuffers(self),
862            #[cfg(feature = "json")]
863            ContentType::Json => json(self),
864            #[cfg(feature = "json5")]
865            ContentType::Json5 => json5(self),
866            #[cfg(feature = "lexpr")]
867            ContentType::Lexpr => lexpr(self),
868            #[cfg(feature = "messagepack")]
869            ContentType::MessagePack => message_pack(self),
870            #[cfg(feature = "pickle")]
871            ContentType::Pickle => pickle(self),
872            #[cfg(feature = "postcard")]
873            ContentType::Postcard => postcard(self),
874            #[cfg(feature = "ron")]
875            ContentType::Ron => ron(self),
876            #[cfg(feature = "toml")]
877            ContentType::Toml => toml(self),
878            #[cfg(feature = "query-string")]
879            ContentType::QueryString => querystring(self),
880            #[cfg(feature = "yaml")]
881            ContentType::Yaml => yaml(self),
882            #[cfg(feature = "accept-limited-xml-serialize")]
883            ContentType::Xml => xml(self),
884        }
885    }
886}
887
888impl<T> SimpleDecoder<Decoded<T>> for Vec<u8>
889    where
890        T: DeserializeOwned,
891{
892    fn decode<F: TryInto<ContentType, Error=impl Into<Error>>>(
893        &self,
894        content_type: F,
895    ) -> Result<Decoded<T>> {
896        self.as_slice().decode(content_type)
897    }
898}
899
900impl<T> SimpleDecoder<Decoded<T>> for &str
901    where
902        T: DeserializeOwned,
903{
904    fn decode<F: TryInto<ContentType, Error=impl Into<Error>>>(
905        &self,
906        content_type: F,
907    ) -> Result<Decoded<T>> {
908        self.as_bytes().decode(content_type)
909    }
910}
911
912impl<T> SimpleDecoder<Decoded<T>> for String
913    where
914        T: DeserializeOwned,
915{
916    fn decode<F: TryInto<ContentType, Error=impl Into<Error>>>(
917        &self,
918        content_type: F,
919    ) -> Result<Decoded<T>> {
920        self.as_bytes().decode(content_type)
921    }
922}
923
924pub struct Encoded {
925    inner: Vec<u8>,
926}
927
928impl PartialEq<Self> for Encoded {
929    fn eq(&self, other: &Self) -> bool {
930        self.inner == other.inner
931    }
932}
933
934impl PartialEq<String> for Encoded {
935    fn eq(&self, other: &String) -> bool {
936        if let Ok(self_string) = self.try_to_string() {
937            self_string == *other
938        } else {
939            false
940        }
941    }
942}
943
944impl PartialEq<&str> for Encoded {
945    fn eq(&self, other: &&str) -> bool {
946        if let Ok(self_string) = self.try_to_string() {
947            self_string == *other
948        } else {
949            false
950        }
951    }
952}
953
954impl Eq for Encoded {}
955
956impl From<Vec<u8>> for Encoded {
957    fn from(v: Vec<u8>) -> Self {
958        Encoded { inner: v }
959    }
960}
961
962impl From<String> for Encoded {
963    fn from(s: String) -> Self {
964        Encoded {
965            inner: s.as_bytes().to_vec(),
966        }
967    }
968}
969
970impl From<&str> for Encoded {
971    fn from(s: &str) -> Self {
972        Encoded {
973            inner: s.as_bytes().to_vec(),
974        }
975    }
976}
977
978impl Deref for Encoded {
979    type Target = Vec<u8>;
980
981    fn deref(&self) -> &Self::Target {
982        &self.inner
983    }
984}
985
986impl DerefMut for Encoded {
987    fn deref_mut(&mut self) -> &mut Self::Target {
988        &mut self.inner
989    }
990}
991
992impl<E> TryFrom<std::result::Result<Vec<u8>, E>> for Encoded
993    where
994        E: Into<Error>,
995{
996    type Error = Error;
997    fn try_from(value: std::result::Result<Vec<u8>, E>) -> std::result::Result<Self, Self::Error> {
998        value.map(Encoded::from).map_err(|e| e.into())
999    }
1000}
1001
1002impl<E> TryFrom<std::result::Result<String, E>> for Encoded
1003    where
1004        E: Into<Error>,
1005{
1006    type Error = Error;
1007    fn try_from(value: std::result::Result<String, E>) -> std::result::Result<Self, Self::Error> {
1008        value.map(Encoded::from).map_err(|e| e.into())
1009    }
1010}
1011
1012impl<E> TryFrom<std::result::Result<&str, E>> for Encoded
1013    where
1014        E: Into<Error>,
1015{
1016    type Error = Error;
1017    fn try_from(value: std::result::Result<&str, E>) -> std::result::Result<Self, Self::Error> {
1018        value.map(Encoded::from).map_err(|e| e.into())
1019    }
1020}
1021
1022impl TryToString for Encoded {
1023    type Error = Error;
1024    fn try_to_string(&self) -> std::result::Result<String, Self::Error> {
1025        from_utf8(self).map_err(Error::from).map(|s| s.to_string())
1026    }
1027}
1028
1029pub struct Decoded<T>
1030    where
1031        T: DeserializeOwned,
1032{
1033    pub(crate) inner: T,
1034}
1035
1036impl<T, E> TryFrom<std::result::Result<T, E>> for Decoded<T>
1037    where
1038        T: DeserializeOwned,
1039        E: Into<Error>,
1040{
1041    type Error = Error;
1042
1043    fn try_from(res: std::result::Result<T, E>) -> std::result::Result<Self, Self::Error> {
1044        res.map_err(|e| e.into()).map(Decoded::from)
1045    }
1046}
1047
1048impl<T: DeserializeOwned> From<T> for Decoded<T> {
1049    fn from(t: T) -> Self {
1050        Decoded { inner: t }
1051    }
1052}
1053
1054impl<T: DeserializeOwned> Deref for Decoded<T> {
1055    type Target = T;
1056
1057    fn deref(&self) -> &Self::Target {
1058        &self.inner
1059    }
1060}
1061
1062impl<T: DeserializeOwned> DerefMut for Decoded<T> {
1063    fn deref_mut(&mut self) -> &mut Self::Target {
1064        &mut self.inner
1065    }
1066}
1067
1068impl<T: DeserializeOwned> Decoded<T> {
1069    pub fn into(self) -> T {
1070        self.inner
1071    }
1072}
1073
1074#[cfg(test)]
1075mod test {
1076    mod test_constants;
1077    mod test_trait_impl;
1078
1079    use super::serde::{Deserialize, Serialize};
1080    use crate::{ContentType, Decoded, Encoded, Error, SimpleDecoder, SimpleEncoder, TryToString};
1081    use std::ops::Deref;
1082    use test_constants::*;
1083
1084    #[derive(Serialize, Deserialize, Debug, PartialEq)]
1085    struct MyStruct {
1086        unquoted: String,
1087        #[serde(rename = "singleQuotes")]
1088        single_quotes: String,
1089        #[serde(rename = "lineBreaks")]
1090        line_breaks: String,
1091        hexadecimal: i32,
1092        #[serde(rename = "leadingDecimalPoint")]
1093        leading_decimal_point: f64,
1094        #[serde(rename = "andTrailing")]
1095        and_trailing: f64,
1096        #[serde(rename = "positiveSign")]
1097        positive_sign: i32,
1098        #[serde(rename = "trailingComma")]
1099        trailing_comma: String,
1100        #[serde(rename = "andIn")]
1101        and_in: Vec<String>,
1102        #[serde(rename = "backwardsCompatible")]
1103        backwards_compatible: String,
1104    }
1105
1106    impl Default for MyStruct {
1107        fn default() -> Self {
1108            MyStruct {
1109                unquoted: "and you can quote me on that".to_string(),
1110                single_quotes: "I can use \"double quotes\" here".to_string(),
1111                line_breaks: "Look, Mom! No \\n's!".to_string(),
1112                hexadecimal: 0xdecaf,
1113                leading_decimal_point: 0.8675309,
1114                and_trailing: 8675309.0,
1115                positive_sign: 1,
1116                trailing_comma: "in objects".to_string(),
1117                and_in: vec!["arrays".to_string(), "arrays-2".to_string()],
1118                backwards_compatible: "with JSON".to_string(),
1119            }
1120        }
1121    }
1122
1123    fn deserialize_test(ser_type: &str, compare_object: &[u8]) {
1124        for i in ["", "application/", "application/x-"] {
1125            let content_type = format!("{}{}", i, ser_type);
1126            let my_struct: Decoded<MyStruct> = compare_object.decode(content_type).unwrap();
1127            println!("Deserialize {} -> {:?}", ser_type, my_struct.deref());
1128            assert_eq!(my_struct.into(), MyStruct::default());
1129        }
1130    }
1131
1132    fn serialize_test(ser_type: &str, compare_object: &[u8]) {
1133        for i in ["", "application/", "application/x-"] {
1134            let my_struct = MyStruct::default();
1135            let serialized = my_struct.encode(format!("{}{}", i, ser_type)).unwrap();
1136            if let Ok(s) = serialized.try_to_string() {
1137                println!("Serialize {} -> {}", ser_type, s);
1138            } else {
1139                println!("Serialize {} -> {:?}", ser_type, serialized.deref());
1140            }
1141
1142            assert_eq!(compare_object, serialized.deref());
1143        }
1144    }
1145
1146    #[test]
1147    fn unknown_content() {
1148        assert_eq!(
1149            Error::UnknownContentTypeMatchFromStr("Foobar".into()),
1150            ContentType::try_from("Foobar").unwrap_err()
1151        );
1152    }
1153
1154    #[test]
1155    fn test_from_str() {
1156        assert_eq!(ContentType::Bson, "Bson".try_into().unwrap());
1157    }
1158
1159    #[test]
1160    fn test_from_ref_string() {
1161        assert_eq!(ContentType::Bson, (&"Bson".to_string()).try_into().unwrap());
1162    }
1163
1164    #[test]
1165    fn test_from_ref_self() {
1166        assert_eq!(
1167            ContentType::Bson,
1168            ContentType::try_from(&ContentType::Bson).unwrap()
1169        );
1170        assert_eq!(
1171            ContentType::Cbor,
1172            ContentType::try_from(&ContentType::Cbor).unwrap()
1173        );
1174        assert_eq!(
1175            ContentType::FlexBuffers,
1176            ContentType::try_from(&ContentType::FlexBuffers).unwrap()
1177        );
1178        assert_eq!(
1179            ContentType::Json,
1180            ContentType::try_from(&ContentType::Json).unwrap()
1181        );
1182        assert_eq!(
1183            ContentType::Json5,
1184            ContentType::try_from(&ContentType::Json5).unwrap()
1185        );
1186        assert_eq!(
1187            ContentType::Lexpr,
1188            ContentType::try_from(&ContentType::Lexpr).unwrap()
1189        );
1190        assert_eq!(
1191            ContentType::MessagePack,
1192            ContentType::try_from(&ContentType::MessagePack).unwrap()
1193        );
1194        assert_eq!(
1195            ContentType::Postcard,
1196            ContentType::try_from(&ContentType::Postcard).unwrap()
1197        );
1198        assert_eq!(
1199            ContentType::Ron,
1200            ContentType::try_from(&ContentType::Ron).unwrap()
1201        );
1202        assert_eq!(
1203            ContentType::Toml,
1204            ContentType::try_from(&ContentType::Toml).unwrap()
1205        );
1206        assert_eq!(
1207            ContentType::QueryString,
1208            ContentType::try_from(&ContentType::QueryString).unwrap()
1209        );
1210        assert_eq!(
1211            ContentType::Yaml,
1212            ContentType::try_from(&ContentType::Yaml).unwrap()
1213        );
1214        assert_eq!(
1215            ContentType::Pickle,
1216            ContentType::try_from(&ContentType::Pickle).unwrap()
1217        );
1218        #[cfg(feature = "accept-limited-xml-serialize")]
1219        assert_eq!(
1220            ContentType::Xml,
1221            ContentType::try_from(&ContentType::Xml).unwrap()
1222        );
1223    }
1224
1225    #[test]
1226    fn test_simple_serialization() {
1227        let my_struct = MyStruct::default();
1228        assert_eq!(
1229            EXAMPLE_JSON_SERIALIZE.as_bytes(),
1230            my_struct.encode("json").unwrap().deref()
1231        );
1232        assert_eq!(
1233            EXAMPLE_JSON_SERIALIZE.as_bytes(),
1234            my_struct.encode("application/json").unwrap().deref()
1235        );
1236    }
1237
1238    #[test]
1239    fn test_simple_deserialization() {
1240        let my_struct: Decoded<MyStruct> =
1241            EXAMPLE_JSON_DESERIALIZE.as_bytes().decode("json").unwrap();
1242        assert_eq!(my_struct.into(), MyStruct::default());
1243    }
1244
1245    #[test]
1246    fn test_yaml() {
1247        deserialize_test("yaml", EXAMPLE_YAML_DESERIALIZE.as_bytes());
1248        serialize_test("yaml", EXAMPLE_YAML_SERIALIZE.as_bytes());
1249    }
1250
1251    #[test]
1252    fn test_json5() {
1253        deserialize_test("json5", EXAMPLE_JSON5_DESERIALIZE.as_bytes());
1254        serialize_test("json5", EXAMPLE_JSON5_SERIALIZE.as_bytes());
1255    }
1256
1257    #[test]
1258    fn test_json() {
1259        deserialize_test("json", EXAMPLE_JSON_DESERIALIZE.as_bytes());
1260        serialize_test("json", EXAMPLE_JSON_SERIALIZE.as_bytes());
1261    }
1262
1263    #[test]
1264    #[cfg(feature = "accept-limited-xml-serialize")]
1265    fn test_xml() {
1266        serialize_test("xml", XML_SERIALIZE.as_bytes());
1267        deserialize_test("xml", XML_DESERIALIZE.as_bytes());
1268    }
1269
1270    #[test]
1271    fn test_cbor() {
1272        serialize_test("cbor", CBOR_SERIALIZE);
1273        deserialize_test("cbor", CBOR_SERIALIZE);
1274    }
1275
1276    #[test]
1277    fn test_bson() {
1278        serialize_test("bson", BSON_SERIALIZE);
1279        deserialize_test("bson", BSON_SERIALIZE);
1280    }
1281
1282    #[test]
1283    fn test_ron() {
1284        serialize_test("ron", RON_SERIALIZE.as_bytes());
1285        deserialize_test("ron", RON_DESERIALIZE.as_bytes());
1286    }
1287
1288    #[test]
1289    fn test_toml() {
1290        serialize_test("toml", TOML_SERIALIZE.as_bytes());
1291        deserialize_test("toml", TOML_SERIALIZE.as_bytes());
1292    }
1293
1294    #[test]
1295    fn test_flex_buffers() {
1296        serialize_test("flexbuffers", FLEXBUFFERS_SERIALIZE);
1297        deserialize_test("flexbuffers", FLEXBUFFERS_SERIALIZE);
1298    }
1299
1300    #[test]
1301    fn test_lexpr() {
1302        serialize_test("lexpr", LEXPR_SERIALIZE.as_bytes());
1303        deserialize_test("lexpr", LEXPR_DESERIALIZE.as_bytes());
1304    }
1305
1306    #[test]
1307    fn test_messagepack() {
1308        serialize_test("messagepack", MESSAGEPACK_SERIALIZE);
1309        deserialize_test("messagepack", MESSAGEPACK_SERIALIZE);
1310    }
1311
1312    #[test]
1313    fn test_pickle() {
1314        serialize_test("pickle", PICKLE_SERIALIZE);
1315        deserialize_test("pickle", PICKLE_SERIALIZE);
1316    }
1317
1318    #[test]
1319    fn test_postcard() {
1320        serialize_test("postcard", POSTCARD_SERIALIZE);
1321        deserialize_test("postcard", POSTCARD_SERIALIZE);
1322    }
1323
1324    #[test]
1325    fn test_url() {
1326        serialize_test("querystring", URL_SERIALIZE.as_bytes());
1327        deserialize_test("querystring", URL_SERIALIZE.as_bytes());
1328    }
1329
1330    #[test]
1331    fn test_error_from_bson_error() {
1332        let err = Error::from(bson::ser::Error::UnsignedIntegerExceededRange(0));
1333        assert!(matches!(err, Error::BsonSerializationFailure(_)));
1334        let err = Error::from(bson::de::Error::EndOfStream);
1335        assert!(matches!(err, Error::BsonDeserializationFailure(_)));
1336    }
1337
1338    #[test]
1339    fn test_documentation_example() {
1340        #[derive(Serialize)]
1341        struct Foo {
1342            bar: String,
1343        }
1344
1345        let my_foo = Foo {
1346            bar: "foobar".to_string(),
1347        };
1348
1349        let encoded: Encoded = my_foo
1350            .encode("yaml")
1351            .expect("Should have been encoded in yaml");
1352
1353        assert_eq!(
1354            &vec![98, 97, 114, 58, 32, 102, 111, 111, 98, 97, 114, 10],
1355            encoded.deref()
1356        );
1357        assert_eq!(
1358            r#"bar: foobar
1359"#,
1360            encoded.try_to_string().unwrap()
1361        )
1362    }
1363}