erased_serde/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
//! [![github]](https://github.com/dtolnay/erased-serde) [![crates-io]](https://crates.io/crates/erased-serde) [![docs-rs]](https://docs.rs/erased-serde)
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
//!
//! <br>
//!
//! This crate provides type-erased versions of Serde's `Serialize`, `Serializer`
//! and `Deserializer` traits that can be used as [trait objects].
//!
//! [trait objects]: https://doc.rust-lang.org/book/trait-objects.html
//!
//! The usual Serde `Serialize`, `Serializer` and `Deserializer` traits cannot
//! be used as trait objects like `&dyn Serialize` or boxed trait objects like
//! `Box<dyn Serialize>` because of Rust's ["object safety" rules]. In
//! particular, all three traits contain generic methods which cannot be made
//! into a trait object.
//!
//! ["object safety" rules]: http://huonw.github.io/blog/2015/01/object-safety/
//!
//! This library should be considered a low-level building block for interacting
//! with Serde APIs in an object-safe way. Most use cases will require higher
//! level functionality such as provided by [`typetag`] which uses this crate
//! internally.
//!
//! [`typetag`]: https://github.com/dtolnay/typetag
//!
//! **The traits in this crate work seamlessly with any existing Serde
//! `Serialize` and `Deserialize` type and any existing Serde `Serializer` and
//! `Deserializer` format.**
//!
//! ## Serialization
//!
//! ```rust
//! use erased_serde::{Serialize, Serializer};
//! use std::collections::BTreeMap as Map;
//! use std::io;
//!
//! fn main() {
//! // Construct some serializers.
//! let json = &mut serde_json::Serializer::new(io::stdout());
//! let cbor = &mut serde_cbor::Serializer::new(serde_cbor::ser::IoWrite::new(io::stdout()));
//!
//! // The values in this map are boxed trait objects. Ordinarily this would not
//! // be possible with serde::Serializer because of object safety, but type
//! // erasure makes it possible with erased_serde::Serializer.
//! let mut formats: Map<&str, Box<dyn Serializer>> = Map::new();
//! formats.insert("json", Box::new(<dyn Serializer>::erase(json)));
//! formats.insert("cbor", Box::new(<dyn Serializer>::erase(cbor)));
//!
//! // These are boxed trait objects as well. Same thing here - type erasure
//! // makes this possible.
//! let mut values: Map<&str, Box<dyn Serialize>> = Map::new();
//! values.insert("vec", Box::new(vec!["a", "b"]));
//! values.insert("int", Box::new(65536));
//!
//! // Pick a Serializer out of the formats map.
//! let format = formats.get_mut("json").unwrap();
//!
//! // Pick a Serialize out of the values map.
//! let value = values.get("vec").unwrap();
//!
//! // This line prints `["a","b"]` to stdout.
//! value.erased_serialize(format).unwrap();
//! }
//! ```
//!
//! ## Deserialization
//!
//! ```rust
//! use erased_serde::Deserializer;
//! use std::collections::BTreeMap as Map;
//!
//! fn main() {
//! static JSON: &'static [u8] = br#"{"A": 65, "B": 66}"#;
//! static CBOR: &'static [u8] = &[162, 97, 65, 24, 65, 97, 66, 24, 66];
//!
//! // Construct some deserializers.
//! let json = &mut serde_json::Deserializer::from_slice(JSON);
//! let cbor = &mut serde_cbor::Deserializer::from_slice(CBOR);
//!
//! // The values in this map are boxed trait objects, which is not possible
//! // with the normal serde::Deserializer because of object safety.
//! let mut formats: Map<&str, Box<dyn Deserializer>> = Map::new();
//! formats.insert("json", Box::new(<dyn Deserializer>::erase(json)));
//! formats.insert("cbor", Box::new(<dyn Deserializer>::erase(cbor)));
//!
//! // Pick a Deserializer out of the formats map.
//! let format = formats.get_mut("json").unwrap();
//!
//! let data: Map<String, usize> = erased_serde::deserialize(format).unwrap();
//!
//! println!("{}", data["A"] + data["B"]);
//! }
//! ```
#![doc(html_root_url = "https://docs.rs/erased-serde/0.4.5")]
#![no_std]
#![deny(unsafe_op_in_unsafe_fn)]
#![allow(
clippy::box_collection,
clippy::derive_partial_eq_without_eq,
clippy::extra_unused_type_parameters,
clippy::items_after_statements,
clippy::manual_map, // https://github.com/rust-lang/rust-clippy/issues/7820
clippy::missing_errors_doc,
clippy::needless_doctest_main,
clippy::needless_pass_by_ref_mut,
clippy::needless_pass_by_value,
clippy::semicolon_if_nothing_returned, // https://github.com/rust-lang/rust-clippy/issues/7324
clippy::similar_names,
clippy::struct_field_names,
clippy::unused_self,
clippy::wildcard_imports
)]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
#[macro_use]
mod macros;
mod any;
mod de;
mod error;
mod features_check;
mod map;
mod sealed;
mod ser;
pub use crate::de::{deserialize, Deserializer};
pub use crate::error::{Error, Result};
pub use crate::ser::{serialize, Serialize, Serializer};
// Not public API.
#[doc(hidden)]
#[path = "private.rs"]
pub mod __private;