1#[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#[cfg(not(tarpaulin_include))]
565impl From<std::convert::Infallible> for Error {
566 fn from(_: Infallible) -> Self {
567 Error::Infallible
568 }
569}
570
571#[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}