miniserde/
lib.rs

1//! [![github]](https://github.com/dtolnay/miniserde) [![crates-io]](https://crates.io/crates/miniserde) [![docs-rs]](https://docs.rs/miniserde)
2//!
3//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
4//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
5//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
6//!
7//! <br>
8//!
9//! *Prototype of a data structure serialization library with several opposite
10//! design goals from [Serde](https://serde.rs).*
11//!
12//! As a prototype, this library is not a production quality engineering
13//! artifact the way Serde is. At the same time, it is more than a proof of
14//! concept and should be totally usable for the range of use cases that it
15//! targets, which is qualified below.
16//!
17//! # Example
18//!
19//! ```rust
20//! use miniserde::{json, Serialize, Deserialize};
21//!
22//! #[derive(Serialize, Deserialize, Debug)]
23//! struct Example {
24//!     code: u32,
25//!     message: String,
26//! }
27//!
28//! fn main() -> miniserde::Result<()> {
29//!     let example = Example {
30//!         code: 200,
31//!         message: "reminiscent of Serde".to_owned(),
32//!     };
33//!
34//!     let j = json::to_string(&example);
35//!     println!("{}", j);
36//!
37//!     let out: Example = json::from_str(&j)?;
38//!     println!("{:?}", out);
39//!
40//!     Ok(())
41//! }
42//! ```
43//!
44//! #
45//!
46//! Here are some similarities and differences compared to Serde.
47//!
48//! ## <font color="#C0C0C0">Similar:</font> Stupidly good performance
49//!
50//! Seriously this library is way faster than it deserves to be. With very
51//! little profiling and optimization so far and opportunities for improvement,
52//! this library is on par with serde\_json for some use cases, slower by a
53//! factor of 1.5 for most, and slower by a factor of 2 for some. That is
54//! remarkable considering the other advantages below.
55//!
56//! ## <font color="#C0C0C0">Similar:</font> Strongly typed data
57//!
58//! Just like Serde, we provide a derive macro for a Serialize and Deserialize
59//! trait. You derive these traits on your own data structures and use
60//! `json::to_string` to convert any Serialize type to JSON and `json::from_str`
61//! to parse JSON into any Deserialize type. Like serde\_json there is a `Value`
62//! enum for embedding untyped components.
63//!
64//! ## <font color="#C0C0C0">Different:</font> Minimal design
65//!
66//! This library does not tackle as expansive of a range of use cases as Serde
67//! does. Feature requests are practically guaranteed to be rejected. If your
68//! use case is not already covered, please use Serde.
69//!
70//! The implementation is less code by a factor of 12 compared to serde +
71//! serde\_derive + serde\_json, and less code even than the `json` crate which
72//! provides no derive macro and cannot manipulate strongly typed data.
73//!
74//! ## <font color="#C0C0C0">Different:</font> No monomorphization
75//!
76//! There are no nontrivial generic methods. All serialization and
77//! deserialization happens in terms of trait objects. Thus no code is compiled
78//! more than once across different generic parameters. In contrast, serde\_json
79//! needs to stamp out a fair amount of generic code for each choice of data
80//! structure being serialized or deserialized.
81//!
82//! Without monomorphization, the derived impls compile lightning fast and
83//! occupy very little size in the executable.
84//!
85//! ## <font color="#C0C0C0">Different:</font> No recursion
86//!
87//! Serde depends on recursion for serialization as well as deserialization.
88//! Every level of nesting in your data means more stack usage until eventually
89//! you overflow the stack. Some formats set a cap on nesting depth to prevent
90//! stack overflows and just refuse to deserialize deeply nested data.
91//!
92//! In miniserde neither serialization nor deserialization involves recursion.
93//! You can safely process arbitrarily nested data without being exposed to
94//! stack overflows. Not even the Drop impl of our json `Value` type is
95//! recursive so you can safely nest them arbitrarily.
96//!
97//! ## <font color="#C0C0C0">Different:</font> No deserialization error messages
98//!
99//! When deserialization fails, the error type is a unit struct containing no
100//! information. This is a legit strategy and not just laziness. If your use
101//! case does not require error messages, good, you save on compiling and having
102//! your instruction cache polluted by error handling code. If you do need error
103//! messages, then upon error you can pass the same input to serde\_json to
104//! receive a line, column, and helpful description of the failure. This keeps
105//! error handling logic out of caches along the performance-critical codepath.
106//!
107//! ## <font color="#C0C0C0">Different:</font> Infallible serialization
108//!
109//! Serialization always succeeds. This means we cannot serialize some data
110//! types that Serde can serialize, such as `Mutex` which may fail to serialize
111//! due to poisoning. Also we only serialize to `String`, not to something like
112//! an i/o stream which may be fallible.
113//!
114//! ## <font color="#C0C0C0">Different:</font> JSON only
115//!
116//! The same approach in this library could be made to work for other data
117//! formats, but it is not a goal to enable that through what this library
118//! exposes.
119//!
120//! ## <font color="#C0C0C0">Different:</font> Structs and unit variants only
121//!
122//! The miniserde derive macros will refuse anything other than a braced struct
123//! with named fields or an enum with C-style variants. Tuple structs are not
124//! supported, and enums with data in their variants are not supported.
125//!
126//! ## <font color="#C0C0C0">Different:</font> No customization
127//!
128//! Serde has tons of knobs for configuring the derived serialization and
129//! deserialization logic through attributes. Or for the ultimate level of
130//! configurability you can handwrite arbitrarily complicated implementations of
131//! its traits.
132//!
133//! Miniserde provides just one attribute which is `rename`, and severely
134//! restricts the kinds of on-the-fly manipulation that are possible in custom
135//! impls. If you need any of this, use Serde -- it's a great library.
136
137#![doc(html_root_url = "https://docs.rs/miniserde/0.1.45")]
138#![allow(
139    clippy::cast_lossless,
140    clippy::cast_possible_truncation,
141    clippy::cast_possible_wrap,
142    clippy::cast_precision_loss,
143    clippy::checked_conversions,
144    clippy::doc_markdown,
145    clippy::elidable_lifetime_names,
146    clippy::enum_glob_use,
147    clippy::into_iter_without_iter, // https://github.com/rust-lang/rust-clippy/issues/11635
148    clippy::let_underscore_untyped,
149    clippy::manual_range_contains,
150    clippy::missing_errors_doc,
151    clippy::module_name_repetitions,
152    clippy::must_use_candidate,
153    clippy::needless_doctest_main,
154    clippy::needless_lifetimes,
155    clippy::redundant_else,
156    clippy::shadow_unrelated,
157    clippy::single_match_else,
158    clippy::too_many_lines,
159    clippy::uninlined_format_args,
160    clippy::useless_transmute, // https://github.com/rust-lang/rust-clippy/issues/5343
161    clippy::vec_init_then_push,
162)]
163#![allow(unknown_lints, mismatched_lifetime_syntaxes)]
164#![no_std]
165
166extern crate alloc;
167
168#[cfg(feature = "std")]
169extern crate std;
170
171#[doc(hidden)]
172pub use mini_internal::*;
173
174// These derives were renamed from MiniTrait -> Trait with the release of Rust
175// 1.30.0. Keep exposing the old names for backward compatibility but remove in
176// the next major version of Miniserde.
177#[doc(hidden)]
178pub use mini_internal::{Deserialize as MiniDeserialize, Serialize as MiniSerialize};
179
180mod export;
181
182include!(concat!(env!("OUT_DIR"), "/private.rs"));
183
184#[macro_use]
185mod careful;
186
187#[macro_use]
188mod place {
189    include!(concat!(env!("OUT_DIR"), "/place.rs"));
190}
191
192mod error;
193mod ignore;
194mod ptr;
195
196pub mod de;
197pub mod json;
198pub mod ser;
199
200#[doc(inline)]
201pub use crate::de::Deserialize;
202pub use crate::error::{Error, Result};
203#[doc(inline)]
204pub use crate::ser::Serialize;
205
206#[allow(non_camel_case_types)]
207struct private;