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