rkyv/lib.rs
1//! rkyv is a zero-copy deserialization framework for Rust.
2//!
3//! ## Overview
4//!
5//! rkyv uses Rust's powerful trait system to serialize data without reflection.
6//! Many zero-copy deserialization frameworks use external schemas and heavily
7//! restrict the available data types. By contrast, rkyv allows all serialized
8//! types to be defined in code and can serialize a wide variety of types that
9//! other frameworks cannot.
10//!
11//! rkyv scales to highly-capable as well as highly-restricted environments. Not
12//! only does rkyv support "no-std" builds for targets without a standard
13//! library implementation, it also supports "no-alloc" builds for targets where
14//! allocations cannot be made.
15//!
16//! rkyv supports limited in-place data mutation, and so can access and update
17//! data without ever deserializing back to native types. When rkyv's in-place
18//! mutation is too limited, rkyv also provides ergonomic and performant
19//! deserialization back into native types.
20//!
21//! rkyv prioritizes performance, and is one of the fastest serialization
22//! frameworks available. All of rkyv's features can be individually enabled and
23//! disabled, so you only pay for what you use. Additionally, all of rkyv's
24//! zero-copy types are designed to have little to no overhead. In most cases,
25//! rkyv's types will have exactly the same performance as native types.
26//!
27//! See the [rkyv book] for guide-level documentation and usage examples.
28//!
29//! [rkyv book]: https://rkyv.org
30//!
31//! ## Components
32//!
33//! rkyv has [a hash map implementation] that is built for zero-copy
34//! deserialization, with the same lookup and iteration performance as the
35//! standard library hash maps. The hash map implementation is based on
36//! [Swiss Tables] and uses a target-independent version of FxHash to ensure
37//! that all targets compute the same hashes.
38//!
39//! It also has [a B-tree implementation] that has the same performance
40//! characteristics as the standard library B-tree maps. Its compact
41//! representation and localized data storage is best-suited for very large
42//! amounts of data.
43//!
44//! rkyv supports [shared pointers] by default, and is able to serialize and
45//! deserialize them without duplicating the underlying data. Shared pointers
46//! which point to the same data when serialized will still point to the same
47//! data when deserialized. By default, rkyv only supports non-cyclic data
48//! structures.
49//!
50//! Alongside its [unchecked API], rkyv also provides optional [validation] so
51//! you can ensure safety and data integrity at the cost of some overhead.
52//! Because checking serialized data can generally be done without allocations,
53//! the cost of checking and zero-copy access can be much lower than that of
54//! traditional deserialization.
55//!
56//! rkyv is trait-oriented from top to bottom, and is made to be extended with
57//! custom and specialized types. Serialization, deserialization, and
58//! validation traits all accept generic context types, making it easy to add
59//! new capabilities without degrading ergonomics.
60//!
61//! [a hash map implementation]: collections::swiss_table::ArchivedHashMap
62//! [Swiss Tables]: https://abseil.io/about/design/swisstables
63//! [a B-tree implementation]: collections::btree_map::ArchivedBTreeMap
64//! [shared pointers]: rc
65//! [unchecked API]: access_unchecked
66//! [validation]: access
67//!
68//! ## Features
69//!
70//! rkyv has several feature flags which can be used to modify its behavior. By
71//! default, rkyv enables the `std`, `alloc`, and `bytecheck` features.
72//!
73//! ### Format control
74//!
75//! These features control how rkyv formats its serialized data. Enabling and
76//! disabling these features may change rkyv's serialized format, and as such
77//! can cause previously-serialized data to become unreadable. Enabling format
78//! control features that are not the default should be considered a breaking
79//! change to rkyv's serialized format.
80//!
81//! Binaries should consider explicitly choosing format control options from the
82//! start, even though doing so is not required. This ensures that developers
83//! stay informed about the specific choices being made, and prevents any
84//! unexpected compatibility issues with libraries they depend on.
85//!
86//! Libraries should avoid enabling format control features unless they intend
87//! to only support rkyv when those specific format control features are
88//! enabled. In general, libraries should be able to support all format control
89//! options if they use rkyv's exported types and aliases.
90//!
91//! #### Endianness
92//!
93//! If an endianness feature is not enabled, rkyv will use little-endian byte
94//! ordering by default.
95//!
96//! - `little_endian`: Forces data serialization to use little-endian byte
97//! ordering. This optimizes serialized data for little-endian architectures.
98//! - `big_endian`: Forces data serialization to use big-endian byte ordering.
99//! This optimizes serialized data for big-endian architectures.
100//!
101//! #### Alignment
102//!
103//! If an alignment feature is not enabled, rkyv will use aligned primitives by
104//! default.
105//!
106//! - `aligned`: Forces data serialization to use aligned primitives. This adds
107//! alignment requirements for accessing data and prevents rkyv from working
108//! with unaligned data.
109//! - `unaligned`: Forces data serialization to use unaligned primitives. This
110//! removes alignment requirements for accessing data and allows rkyv to work
111//! with unaligned data more easily.
112//!
113//! #### Pointer width
114//!
115//! If a pointer width feature is not enabled, rkyv will serialize `isize` and
116//! `usize` as 32-bit integers by default.
117//!
118//! - `pointer_width_16`: Serializes `isize` and `usize` as 16-bit integers.
119//! This is intended to be used only for small data sizes and may not handle
120//! large amounts of data.
121//! - `pointer_width_32`: Serializes `isize` and `usize` as 32-bit integers.
122//! This is a good choice for most data, and balances the storage overhead
123//! with support for large data sizes.
124//! - `pointer_width_64`: Serializes `isize` and `usize` as 64-bit integers.
125//! This is intended to be used only for extremely large data sizes and may
126//! cause unnecessary data bloat for smaller amounts of data.
127//!
128//! ### Functionality
129//!
130//! These features enable more built-in functionality and provide more powerful
131//! and ergonomic APIs. Enabling and disabling these features does not change
132//! rkyv's serialized format.
133//!
134//! - `alloc`: Enables support for the `alloc` crate. Enabled by default.
135//! - `std`: Enables standard library support. Enabled by default.
136//! - `bytecheck`: Enables data validation through `bytecheck`. Enabled by
137//! default.
138//!
139//! ### Crates
140//!
141//! rkyv provides integrations for some common crates by default. In the future,
142//! crates should depend on rkyv and provide their own integration. Enabling and
143//! disabling these features does not change rkyv's serialized format.
144//!
145//! - [`arrayvec-0_7`](https://docs.rs/arrayvec/0.7)
146//! - [`bytes-1`](https://docs.rs/bytes/1)
147//! - [`hashbrown-0_14`](https://docs.rs/hashbrown/0.14)
148//! - [`hashbrown-0_15`](https://docs.rs/hashbrown/0.15)
149//! - [`indexmap-2`](https://docs.rs/indexmap/2)
150//! - [`smallvec-1`](https://docs.rs/smallvec/1)
151//! - [`smol_str-0_2`](https://docs.rs/smol_str/0.2)
152//! - [`smol_str-0_3`](https://docs.rs/smol_str/0.3)
153//! - [`thin-vec-0_2`](https://docs.rs/thin-vec/0.2)
154//! - [`tinyvec-1`](https://docs.rs/tinyvec/1)
155//! - [`triomphe-0_1`](https://docs.rs/triomphe/0.1)
156//! - [`uuid-1`](https://docs.rs/uuid/1)
157//!
158//! ## Compatibility
159//!
160//! Serialized data can be accessed later as long as:
161//!
162//! - The underlying schema has not changed
163//! - The serialized format has not been changed by format control features
164//! - The data was serialized by a semver-compatible version of rkyv
165
166// Crate attributes
167
168#![deny(
169 future_incompatible,
170 missing_docs,
171 nonstandard_style,
172 unsafe_op_in_unsafe_fn,
173 unused,
174 warnings,
175 clippy::all,
176 clippy::missing_safety_doc,
177 // TODO(#114): re-enable this lint after justifying unsafe blocks
178 // clippy::undocumented_unsafe_blocks,
179 rustdoc::broken_intra_doc_links,
180 rustdoc::missing_crate_level_docs
181)]
182#![cfg_attr(not(feature = "std"), no_std)]
183#![cfg_attr(all(docsrs, not(doctest)), feature(doc_cfg, doc_auto_cfg))]
184#![doc(html_favicon_url = r#"
185 data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0
186 26.458 26.458'%3E%3Cpath d='M0 0v26.458h26.458V0zm9.175 3.772l8.107 8.106
187 2.702-2.702 2.702 13.512-13.512-2.702 2.703-2.702-8.107-8.107z'/%3E
188 %3C/svg%3E
189"#)]
190#![doc(html_logo_url = r#"
191 data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="100"
192 height="100" viewBox="0 0 26.458 26.458"%3E%3Cpath d="M0
193 0v26.458h26.458V0zm9.175 3.772l8.107 8.106 2.702-2.702 2.702
194 13.512-13.512-2.702 2.703-2.702-8.107-8.107z"/%3E%3C/svg%3E
195"#)]
196#![cfg_attr(miri, feature(alloc_layout_extra))]
197
198// Extern crates
199
200#[cfg(all(feature = "alloc", not(feature = "std")))]
201extern crate alloc;
202#[cfg(feature = "std")]
203use std as alloc;
204
205// Re-exports
206#[cfg(feature = "bytecheck")]
207pub use ::bytecheck;
208pub use ::munge;
209pub use ::ptr_meta;
210pub use ::rancor;
211pub use ::rend;
212
213// Modules
214
215mod alias;
216#[macro_use]
217mod _macros;
218pub mod api;
219pub mod boxed;
220pub mod collections;
221pub mod de;
222pub mod ffi;
223mod fmt;
224pub mod hash;
225mod impls;
226pub mod net;
227pub mod niche;
228pub mod ops;
229pub mod option;
230pub mod place;
231mod polyfill;
232pub mod primitive;
233pub mod rc;
234pub mod rel_ptr;
235pub mod result;
236pub mod seal;
237pub mod ser;
238mod simd;
239pub mod string;
240pub mod time;
241pub mod traits;
242pub mod tuple;
243pub mod util;
244#[cfg(feature = "bytecheck")]
245pub mod validation;
246pub mod vec;
247pub mod with;
248
249// Exports
250
251#[cfg(all(feature = "bytecheck", feature = "alloc"))]
252#[doc(inline)]
253pub use api::high::{access, access_mut, from_bytes};
254#[cfg(feature = "alloc")]
255#[doc(inline)]
256pub use api::high::{deserialize, from_bytes_unchecked, to_bytes};
257
258#[doc(inline)]
259pub use crate::{
260 alias::*,
261 api::{access_unchecked, access_unchecked_mut},
262 place::Place,
263 traits::{
264 Archive, ArchiveUnsized, Deserialize, DeserializeUnsized, Portable,
265 Serialize, SerializeUnsized,
266 },
267};
268
269// Check endianness feature flag settings
270
271#[cfg(all(feature = "little_endian", feature = "big_endian"))]
272core::compiler_error!(
273 "\"little_endian\" and \"big_endian\" are mutually-exclusive features. \
274 You may need to set `default-features = false` or compile with \
275 `--no-default-features`."
276);
277
278// Check alignment feature flag settings
279
280#[cfg(all(feature = "aligned", feature = "unaligned"))]
281core::compiler_error!(
282 "\"aligned\" and \"unaligned\" are mutually-exclusive features. You may \
283 need to set `default-features = false` or compile with \
284 `--no-default-features`."
285);
286
287// Check pointer width feature flag settings
288
289#[cfg(all(
290 feature = "pointer_width_16",
291 feature = "pointer_width_32",
292 not(feature = "pointer_width_64")
293))]
294core::compile_error!(
295 "\"pointer_width_16\" and \"pointer_width_32\" are mutually-exclusive \
296 features. You may need to set `default-features = false` or compile with \
297 `--no-default-features`."
298);
299#[cfg(all(
300 feature = "pointer_width_16",
301 feature = "pointer_width_64",
302 not(feature = "pointer_width_32")
303))]
304core::compile_error!(
305 "\"pointer_width_16\" and \"pointer_width_64\" are mutually-exclusive \
306 features. You may need to set `default-features = false` or compile with \
307 `--no-default-features`."
308);
309#[cfg(all(
310 feature = "pointer_width_32",
311 feature = "pointer_width_64",
312 not(feature = "pointer_width_16")
313))]
314core::compile_error!(
315 "\"pointer_width_32\" and \"pointer_width_64\" are mutually-exclusive \
316 features. You may need to set `default-features = false` or compile with \
317 `--no-default-features`."
318);
319#[cfg(all(
320 feature = "pointer_width_16",
321 feature = "pointer_width_32",
322 feature = "pointer_width_64"
323))]
324core::compile_error!(
325 "\"pointer_width_16\", \"pointer_width_32\", and \"pointer_width_64\" are \
326 mutually-exclusive features. You may need to set `default-features = \
327 false` or compile with `--no-default-features`."
328);