/rust/registry/src/index.crates.io-6f17d22bba15001f/rkyv-0.7.44/src/lib.rs
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | //! # rkyv | 
| 2 |  | //! | 
| 3 |  | //! rkyv (*archive*) is a zero-copy deserialization framework for Rust. | 
| 4 |  | //! | 
| 5 |  | //! It's similar to other zero-copy deserialization frameworks such as | 
| 6 |  | //! [Cap'n Proto](https://capnproto.org) and [FlatBuffers](https://google.github.io/flatbuffers). | 
| 7 |  | //! However, while the former have external schemas and heavily restricted data types, rkyv allows | 
| 8 |  | //! all serialized types to be defined in code and can serialize a wide variety of types that the | 
| 9 |  | //! others cannot. Additionally, rkyv is designed to have little to no overhead, and in most cases | 
| 10 |  | //! will perform exactly the same as native types. | 
| 11 |  | //! | 
| 12 |  | //! ## Design | 
| 13 |  | //! | 
| 14 |  | //! Like [serde](https://serde.rs), rkyv uses Rust's powerful trait system to serialize data without | 
| 15 |  | //! the need for reflection. Despite having a wide array of features, you also only pay for what you | 
| 16 |  | //! use. If your data checks out, the serialization process can be as simple as a `memcpy`! Like | 
| 17 |  | //! serde, this allows rkyv to perform at speeds similar to handwritten serializers. | 
| 18 |  | //! | 
| 19 |  | //! Unlike serde, rkyv produces data that is guaranteed deserialization free. If you wrote your data | 
| 20 |  | //! to disk, you can just `mmap` your file into memory, cast a pointer, and your data is ready to | 
| 21 |  | //! use. This makes it ideal for high-performance and IO-bound applications. | 
| 22 |  | //! | 
| 23 |  | //! Limited data mutation is supported through `Pin` APIs, and archived values can be truly | 
| 24 |  | //! deserialized with [`Deserialize`] if full mutation capabilities are needed. | 
| 25 |  | //! | 
| 26 |  | //! [The book](https://rkyv.org) has more details on the design and capabilities of rkyv. | 
| 27 |  | //! | 
| 28 |  | //! ## Type support | 
| 29 |  | //! | 
| 30 |  | //! rkyv has a hashmap implementation that is built for zero-copy deserialization, so you can | 
| 31 |  | //! serialize your hashmaps with abandon. The implementation performs perfect hashing with the | 
| 32 |  | //! compress, hash and displace algorithm to use as little memory as possible while still performing | 
| 33 |  | //! fast lookups. | 
| 34 |  | //! | 
| 35 |  | //! It also comes with a B+ tree implementation that is built for maximum performance by splitting | 
| 36 |  | //! data into easily-pageable 4KB segments. This makes it perfect for building immutable databases | 
| 37 |  | //! and structures for bulk data. | 
| 38 |  | //! | 
| 39 |  | //! rkyv also has support for contextual serialization, deserialization, and validation. It can | 
| 40 |  | //! properly serialize and deserialize shared pointers like `Rc` and `Arc`, and can be extended to | 
| 41 |  | //! support custom contextual types. | 
| 42 |  | //! | 
| 43 |  | //! Finally, rkyv makes it possible to serialize trait objects and use them *as trait objects* | 
| 44 |  | //! without deserialization. See the `archive_dyn` crate for more details. | 
| 45 |  | //! | 
| 46 |  | //! ## Tradeoffs | 
| 47 |  | //! | 
| 48 |  | //! While rkyv is a great format for final data, it lacks a full schema system and isn't well | 
| 49 |  | //! equipped for data migration and schema upgrades. If your use case requires these capabilities, | 
| 50 |  | //! you may need additional libraries the build these features on top of rkyv. You can use other | 
| 51 |  | //! serialization frameworks like serde with the same types as rkyv conflict-free. | 
| 52 |  | //! | 
| 53 |  | //! ## Features | 
| 54 |  | //! | 
| 55 |  | //! - `alloc`: Enables types that require the `alloc` crate. Enabled by default. | 
| 56 |  | //! - `arbitrary_enum_discriminant`: Enables the `arbitrary_enum_discriminant` feature for stable | 
| 57 |  | //!   multibyte enum discriminants using `archive_le` and `archive_be`. Requires nightly. | 
| 58 |  | //! - `archive_be`: Forces archives into a big-endian format. This guarantees cross-endian | 
| 59 |  | //!   compatibility optimized for big-endian architectures. | 
| 60 |  | //! - `archive_le`: Forces archives into a little-endian format. This guarantees cross-endian | 
| 61 |  | //!   compatibility optimized for little-endian architectures. | 
| 62 |  | //! - `copy`: Enables copy optimizations for packed copyable data types. Requires nightly. | 
| 63 |  | //! - `copy_unsafe`: Automatically opts all potentially copyable types into copy optimization. This | 
| 64 |  | //!   broadly improves performance but may cause uninitialized bytes to be copied to the output. | 
| 65 |  | //!   Requires nightly. | 
| 66 |  | //! - `size_16`: Archives integral `*size` types as 16-bit integers. This is intended to be used | 
| 67 |  | //!   only for small archives and may not handle large, more general data. | 
| 68 |  | //! - `size_32`: Archives integral `*size` types as 32-bit integers. Enabled by default. | 
| 69 |  | //! - `size_64`: Archives integral `*size` types as 64-bit integers. This is intended to be used | 
| 70 |  | //!   only for very large archives and may cause unnecessary data bloat. | 
| 71 |  | //! - `std`: Enables standard library support. Enabled by default. | 
| 72 |  | //! - `strict`: Guarantees that types will have the same representations across platforms and | 
| 73 |  | //!   compilations. This is already the case in practice, but this feature provides a guarantee | 
| 74 |  | //!   along with C type compatibility. | 
| 75 |  | //! | 
| 76 |  | //!   *Note*: Enabling `strict` will disable [`Archive`] implementations for tuples, as tuples | 
| 77 |  | //!   do not have a C type layout. Making a generic `Tuple<T1, T2>` and deriving [`Archive`] for it | 
| 78 |  | //!   should provide similar functionality. | 
| 79 |  | //! - `validation`: Enables validation support through `bytecheck`. | 
| 80 |  | //! | 
| 81 |  | //! ## Crate support | 
| 82 |  | //! | 
| 83 |  | //! Some common crates need to be supported by rkyv before an official integration has been made. | 
| 84 |  | //! Support is provided by rkyv for these crates, but in the future crates should depend on rkyv and | 
| 85 |  | //! provide their own implementations. The crates that already have support provided by rkyv should | 
| 86 |  | //! work toward integrating the implementations into themselves. | 
| 87 |  | //! | 
| 88 |  | //! Crates supported by rkyv: | 
| 89 |  | //! | 
| 90 |  | //! - [`indexmap`](https://docs.rs/indexmap) | 
| 91 |  | //! - [`rend`](https://docs.rs/rend) *Enabled automatically when using endian-specific archive | 
| 92 |  | //!   features.* | 
| 93 |  | //! - [`tinyvec`](https://docs.rs/tinyvec) | 
| 94 |  | //! - [`uuid`](https://docs.rs/uuid) | 
| 95 |  | //! | 
| 96 |  | //! Support for each of these crates can be enabled with a feature of the same name. Additionally, | 
| 97 |  | //! the following external crate features are available: | 
| 98 |  | //! | 
| 99 |  | //! - `alloc` with `tinyvec/alloc`: Supports types behind the `alloc` feature in `tinyvec`. | 
| 100 |  | //! - `std` with `uuid/std`: Enables the `std` feature in `uuid`. | 
| 101 |  | //! | 
| 102 |  | //! ## Examples | 
| 103 |  | //! | 
| 104 |  | //! - See [`Archive`] for examples of how to use rkyv through the derive macro and manual | 
| 105 |  | //!   implementation. | 
| 106 |  | //! - For more details on the derive macro and its capabilities, see | 
| 107 |  | //!   [`Archive`](macro@Archive). | 
| 108 |  | //! - Fully worked examples using rkyv are available in the | 
| 109 |  | //!   [`examples` directory](https://github.com/rkyv/rkyv/tree/master/examples) of the source repo. | 
| 110 |  |  | 
| 111 |  | #![deny( | 
| 112 |  |     rustdoc::broken_intra_doc_links, | 
| 113 |  |     missing_docs, | 
| 114 |  |     rustdoc::missing_crate_level_docs | 
| 115 |  | )] | 
| 116 |  | #![cfg_attr(not(feature = "std"), no_std)] | 
| 117 |  | #![cfg_attr( | 
| 118 |  |     feature = "copy", | 
| 119 |  |     feature(auto_traits), | 
| 120 |  |     feature(min_specialization), | 
| 121 |  |     feature(negative_impls), | 
| 122 |  |     feature(rustc_attrs) | 
| 123 |  | )] | 
| 124 |  | #![doc(html_favicon_url = r#" | 
| 125 |  |     data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' | 
| 126 |  |     viewBox='0 0 26.458 26.458'%3E%3Cpath d='M0 0v26.458h26.458V0zm9.175 3.772l8.107 8.106 | 
| 127 |  |     2.702-2.702 2.702 13.512-13.512-2.702 2.703-2.702-8.107-8.107z'/%3E%3C/svg%3E | 
| 128 |  | "#)] | 
| 129 |  | #![doc(html_logo_url = r#" | 
| 130 |  |     data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="100" height="100" | 
| 131 |  |     viewBox="0 0 26.458 26.458"%3E%3Cpath d="M0 0v26.458h26.458V0zm9.175 3.772l8.107 8.106 | 
| 132 |  |     2.702-2.702 2.702 13.512-13.512-2.702 2.703-2.702-8.107-8.107z"/%3E%3C/svg%3E | 
| 133 |  | "#)] | 
| 134 |  | // Only use this feature if you know what you're doing! | 
| 135 |  | #![cfg_attr(feature = "copy", allow(internal_features))] | 
| 136 |  |  | 
| 137 |  | #[cfg(all(feature = "alloc", not(feature = "std")))] | 
| 138 |  | extern crate alloc; | 
| 139 |  | #[cfg(feature = "std")] | 
| 140 |  | extern crate std; | 
| 141 |  |  | 
| 142 |  | #[doc(hidden)] | 
| 143 |  | #[macro_use] | 
| 144 |  | pub mod macros; | 
| 145 |  |  | 
| 146 |  | #[cfg(feature = "bitvec")] | 
| 147 |  | pub mod bitvec; | 
| 148 |  | pub mod boxed; | 
| 149 |  | pub mod collections; | 
| 150 |  | #[cfg(feature = "copy")] | 
| 151 |  | pub mod copy; | 
| 152 |  | pub mod de; | 
| 153 |  | // This is pretty unfortunate. CStr doesn't rely on the rest of std, but it's not in core. | 
| 154 |  | // If CStr ever gets moved into `core` then this module will no longer need cfg(feature = "std") | 
| 155 |  | #[cfg(feature = "std")] | 
| 156 |  | pub mod ffi; | 
| 157 |  | mod impls; | 
| 158 |  | pub mod net; | 
| 159 |  | pub mod niche; | 
| 160 |  | pub mod ops; | 
| 161 |  | pub mod option; | 
| 162 |  | pub mod rc; | 
| 163 |  | pub mod rel_ptr; | 
| 164 |  | pub mod result; | 
| 165 |  | pub mod ser; | 
| 166 |  | pub mod string; | 
| 167 |  | pub mod time; | 
| 168 |  | pub mod util; | 
| 169 |  | #[cfg(feature = "validation")] | 
| 170 |  | pub mod validation; | 
| 171 |  | pub mod vec; | 
| 172 |  | pub mod with; | 
| 173 |  |  | 
| 174 |  | #[cfg(feature = "rend")] | 
| 175 |  | pub use rend; | 
| 176 |  |  | 
| 177 |  | #[cfg(feature = "validation")] | 
| 178 |  | #[cfg_attr(doc_cfg, doc(cfg(feature = "validation")))] | 
| 179 |  | pub use bytecheck::{self, CheckBytes}; | 
| 180 |  | use core::alloc::Layout; | 
| 181 |  | use ptr_meta::Pointee; | 
| 182 |  | pub use rkyv_derive::{Archive, Deserialize, Serialize}; | 
| 183 |  | pub use util::*; | 
| 184 |  | #[cfg(feature = "validation")] | 
| 185 |  | #[cfg_attr(doc_cfg, doc(cfg(feature = "validation")))] | 
| 186 |  | pub use validation::{ | 
| 187 |  |     check_archived_root_with_context, check_archived_value_with_context, | 
| 188 |  |     validators::{check_archived_root, check_archived_value, from_bytes}, | 
| 189 |  | }; | 
| 190 |  |  | 
| 191 |  | /// A type that can produce an error. | 
| 192 |  | /// | 
| 193 |  | /// This trait is always implemented by serializers and deserializers. Its purpose is to provide an | 
| 194 |  | /// error type without restricting what other capabilities the type must provide. | 
| 195 |  | /// | 
| 196 |  | /// When writing implementations for [`Serialize`] and [`Deserialize`], it's best practice to bound | 
| 197 |  | /// the serializer or deserializer by `Fallible` and then require that the serialized types support | 
| 198 |  | /// it (i.e. `S: Fallible, MyType: Serialize<S>`). | 
| 199 |  | pub trait Fallible { | 
| 200 |  |     /// The error produced by any failing methods. | 
| 201 |  |     type Error: 'static; | 
| 202 |  | } | 
| 203 |  |  | 
| 204 |  | /// A fallible type that cannot produce errors. | 
| 205 |  | /// | 
| 206 |  | /// This type can be used to serialize and deserialize types that cannot fail to serialize or | 
| 207 |  | /// deserialize. | 
| 208 |  | #[derive(Debug)] | 
| 209 |  | pub struct Infallible; | 
| 210 |  |  | 
| 211 |  | impl Fallible for Infallible { | 
| 212 |  |     type Error = core::convert::Infallible; | 
| 213 |  | } | 
| 214 |  |  | 
| 215 |  | impl Default for Infallible { | 
| 216 | 0 |     fn default() -> Self { | 
| 217 | 0 |         Infallible | 
| 218 | 0 |     } Unexecuted instantiation: <rkyv::Infallible as core::default::Default>::defaultUnexecuted instantiation: <rkyv::Infallible as core::default::Default>::default | 
| 219 |  | } | 
| 220 |  |  | 
| 221 |  | /// A type that can be used without deserializing. | 
| 222 |  | /// | 
| 223 |  | /// `Archive` is one of three basic traits used to work with zero-copy data and controls the layout | 
| 224 |  | /// of the data in its archived zero-copy representation. The [`Serialize`] trait helps transform | 
| 225 |  | /// types into that representation, and the [`Deserialize`] trait helps transform types back out. | 
| 226 |  | /// | 
| 227 |  | /// Types that implement `Archive` must have a well-defined archived size. Unsized types can be | 
| 228 |  | /// supported using the [`ArchiveUnsized`] trait, along with [`SerializeUnsized`] and | 
| 229 |  | /// [`DeserializeUnsized`]. | 
| 230 |  | /// | 
| 231 |  | /// Archiving is done depth-first, writing any data owned by a type before writing the data for the | 
| 232 |  | /// type itself. The type must be able to create the archived type from only its own data and its | 
| 233 |  | /// resolver. | 
| 234 |  | /// | 
| 235 |  | /// Archived data is always treated as if it is tree-shaped, with the root owning its direct | 
| 236 |  | /// descendents and so on. Data that is not tree-shaped can be supported using special serializer | 
| 237 |  | /// and deserializer bounds (see [`ArchivedRc`](crate::rc::ArchivedRc) for example). In a buffer of | 
| 238 |  | /// serialized data, objects are laid out in *reverse order*. This means that the root object is | 
| 239 |  | /// located near the end of the buffer and leaf objects are located near the beginning. | 
| 240 |  | /// | 
| 241 |  | /// # Examples | 
| 242 |  | /// | 
| 243 |  | /// Most of the time, `#[derive(Archive)]` will create an acceptable implementation. You can use the | 
| 244 |  | /// `#[archive(...)]` and `#[archive_attr(...)]` attributes to control how the implementation is | 
| 245 |  | /// generated. See the [`Archive`](macro@Archive) derive macro for more details. | 
| 246 |  | /// | 
| 247 |  | /// ``` | 
| 248 |  | /// use rkyv::{Archive, Deserialize, Serialize}; | 
| 249 |  | /// | 
| 250 |  | /// #[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] | 
| 251 |  | /// // This will generate a PartialEq impl between our unarchived and archived types | 
| 252 |  | /// #[archive(compare(PartialEq))] | 
| 253 |  | /// // We can pass attributes through to generated types with archive_attr | 
| 254 |  | /// #[archive_attr(derive(Debug))] | 
| 255 |  | /// struct Test { | 
| 256 |  | ///     int: u8, | 
| 257 |  | ///     string: String, | 
| 258 |  | ///     option: Option<Vec<i32>>, | 
| 259 |  | /// } | 
| 260 |  | /// | 
| 261 |  | /// let value = Test { | 
| 262 |  | ///     int: 42, | 
| 263 |  | ///     string: "hello world".to_string(), | 
| 264 |  | ///     option: Some(vec![1, 2, 3, 4]), | 
| 265 |  | /// }; | 
| 266 |  | /// | 
| 267 |  | /// // Serializing is as easy as a single function call | 
| 268 |  | /// let bytes = rkyv::to_bytes::<_, 256>(&value).unwrap(); | 
| 269 |  | /// | 
| 270 |  | /// // Or you can customize your serialization for better performance | 
| 271 |  | /// // and compatibility with #![no_std] environments | 
| 272 |  | /// use rkyv::ser::{Serializer, serializers::AllocSerializer}; | 
| 273 |  | /// | 
| 274 |  | /// let mut serializer = AllocSerializer::<0>::default(); | 
| 275 |  | /// serializer.serialize_value(&value).unwrap(); | 
| 276 |  | /// let bytes = serializer.into_serializer().into_inner(); | 
| 277 |  | /// | 
| 278 |  | /// // You can use the safe API with the validation feature turned on, | 
| 279 |  | /// // or you can use the unsafe API (shown here) for maximum performance | 
| 280 |  | /// let archived = unsafe { rkyv::archived_root::<Test>(&bytes[..]) }; | 
| 281 |  | /// assert_eq!(archived, &value); | 
| 282 |  | /// | 
| 283 |  | /// // And you can always deserialize back to the original type | 
| 284 |  | /// let deserialized: Test = archived.deserialize(&mut rkyv::Infallible).unwrap(); | 
| 285 |  | /// assert_eq!(deserialized, value); | 
| 286 |  | /// ``` | 
| 287 |  | /// | 
| 288 |  | /// _Note: the safe API requires the `validation` feature._ | 
| 289 |  | /// | 
| 290 |  | /// Many of the core and standard library types already have `Archive` implementations available, | 
| 291 |  | /// but you may need to implement `Archive` for your own types in some cases the derive macro cannot | 
| 292 |  | /// handle. | 
| 293 |  | /// | 
| 294 |  | /// In this example, we add our own wrapper that serializes a `&'static str` as if it's owned. | 
| 295 |  | /// Normally you can lean on the archived version of `String` to do most of the work, or use the | 
| 296 |  | /// [`Inline`](crate::with::Inline) to do exactly this. This example does everything to demonstrate | 
| 297 |  | /// how to implement `Archive` for your own types. | 
| 298 |  | /// | 
| 299 |  | /// ``` | 
| 300 |  | /// use core::{slice, str}; | 
| 301 |  | /// use rkyv::{ | 
| 302 |  | ///     archived_root, | 
| 303 |  | ///     ser::{Serializer, serializers::AlignedSerializer}, | 
| 304 |  | ///     out_field, | 
| 305 |  | ///     AlignedVec, | 
| 306 |  | ///     Archive, | 
| 307 |  | ///     Archived, | 
| 308 |  | ///     ArchiveUnsized, | 
| 309 |  | ///     MetadataResolver, | 
| 310 |  | ///     RelPtr, | 
| 311 |  | ///     Serialize, | 
| 312 |  | ///     SerializeUnsized, | 
| 313 |  | /// }; | 
| 314 |  | /// | 
| 315 |  | /// struct OwnedStr { | 
| 316 |  | ///     inner: &'static str, | 
| 317 |  | /// } | 
| 318 |  | /// | 
| 319 |  | /// struct ArchivedOwnedStr { | 
| 320 |  | ///     // This will be a relative pointer to our string | 
| 321 |  | ///     ptr: RelPtr<str>, | 
| 322 |  | /// } | 
| 323 |  | /// | 
| 324 |  | /// impl ArchivedOwnedStr { | 
| 325 |  | ///     // This will help us get the bytes of our type as a str again. | 
| 326 |  | ///     fn as_str(&self) -> &str { | 
| 327 |  | ///         unsafe { | 
| 328 |  | ///             // The as_ptr() function of RelPtr will get a pointer the str | 
| 329 |  | ///             &*self.ptr.as_ptr() | 
| 330 |  | ///         } | 
| 331 |  | ///     } | 
| 332 |  | /// } | 
| 333 |  | /// | 
| 334 |  | /// struct OwnedStrResolver { | 
| 335 |  | ///     // This will be the position that the bytes of our string are stored at. | 
| 336 |  | ///     // We'll use this to resolve the relative pointer of our | 
| 337 |  | ///     // ArchivedOwnedStr. | 
| 338 |  | ///     pos: usize, | 
| 339 |  | ///     // The archived metadata for our str may also need a resolver. | 
| 340 |  | ///     metadata_resolver: MetadataResolver<str>, | 
| 341 |  | /// } | 
| 342 |  | /// | 
| 343 |  | /// // The Archive implementation defines the archived version of our type and | 
| 344 |  | /// // determines how to turn the resolver into the archived form. The Serialize | 
| 345 |  | /// // implementations determine how to make a resolver from the original value. | 
| 346 |  | /// impl Archive for OwnedStr { | 
| 347 |  | ///     type Archived = ArchivedOwnedStr; | 
| 348 |  | ///     // This is the resolver we can create our Archived version from. | 
| 349 |  | ///     type Resolver = OwnedStrResolver; | 
| 350 |  | /// | 
| 351 |  | ///     // The resolve function consumes the resolver and produces the archived | 
| 352 |  | ///     // value at the given position. | 
| 353 |  | ///     unsafe fn resolve( | 
| 354 |  | ///         &self, | 
| 355 |  | ///         pos: usize, | 
| 356 |  | ///         resolver: Self::Resolver, | 
| 357 |  | ///         out: *mut Self::Archived, | 
| 358 |  | ///     ) { | 
| 359 |  | ///         // We have to be careful to add the offset of the ptr field, | 
| 360 |  | ///         // otherwise we'll be using the position of the ArchivedOwnedStr | 
| 361 |  | ///         // instead of the position of the relative pointer. | 
| 362 |  | ///         let (fp, fo) = out_field!(out.ptr); | 
| 363 |  | ///         self.inner.resolve_unsized( | 
| 364 |  | ///             pos + fp, | 
| 365 |  | ///             resolver.pos, | 
| 366 |  | ///             resolver.metadata_resolver, | 
| 367 |  | ///             fo, | 
| 368 |  | ///         ); | 
| 369 |  | ///     } | 
| 370 |  | /// } | 
| 371 |  | /// | 
| 372 |  | /// // We restrict our serializer types with Serializer because we need its | 
| 373 |  | /// // capabilities to archive our type. For other types, we might need more or | 
| 374 |  | /// // less restrictive bounds on the type of S. | 
| 375 |  | /// impl<S: Serializer + ?Sized> Serialize<S> for OwnedStr { | 
| 376 |  | ///     fn serialize( | 
| 377 |  | ///         &self, | 
| 378 |  | ///         serializer: &mut S | 
| 379 |  | ///     ) -> Result<Self::Resolver, S::Error> { | 
| 380 |  | ///         // This is where we want to write the bytes of our string and return | 
| 381 |  | ///         // a resolver that knows where those bytes were written. | 
| 382 |  | ///         // We also need to serialize the metadata for our str. | 
| 383 |  | ///         Ok(OwnedStrResolver { | 
| 384 |  | ///             pos: self.inner.serialize_unsized(serializer)?, | 
| 385 |  | ///             metadata_resolver: self.inner.serialize_metadata(serializer)? | 
| 386 |  | ///         }) | 
| 387 |  | ///     } | 
| 388 |  | /// } | 
| 389 |  | /// | 
| 390 |  | /// let mut serializer = AlignedSerializer::new(AlignedVec::new()); | 
| 391 |  | /// const STR_VAL: &'static str = "I'm in an OwnedStr!"; | 
| 392 |  | /// let value = OwnedStr { inner: STR_VAL }; | 
| 393 |  | /// // It works! | 
| 394 |  | /// serializer.serialize_value(&value).expect("failed to archive test"); | 
| 395 |  | /// let buf = serializer.into_inner(); | 
| 396 |  | /// let archived = unsafe { archived_root::<OwnedStr>(buf.as_ref()) }; | 
| 397 |  | /// // Let's make sure our data got written correctly | 
| 398 |  | /// assert_eq!(archived.as_str(), STR_VAL); | 
| 399 |  | /// ``` | 
| 400 |  | pub trait Archive { | 
| 401 |  |     /// The archived representation of this type. | 
| 402 |  |     /// | 
| 403 |  |     /// In this form, the data can be used with zero-copy deserialization. | 
| 404 |  |     type Archived; | 
| 405 |  |  | 
| 406 |  |     /// The resolver for this type. It must contain all the additional information from serializing | 
| 407 |  |     /// needed to make the archived type from the normal type. | 
| 408 |  |     type Resolver; | 
| 409 |  |  | 
| 410 |  |     /// Creates the archived version of this value at the given position and writes it to the given | 
| 411 |  |     /// output. | 
| 412 |  |     /// | 
| 413 |  |     /// The output should be initialized field-by-field rather than by writing a whole struct. | 
| 414 |  |     /// Performing a typed copy will mark all of the padding bytes as uninitialized, but they must | 
| 415 |  |     /// remain set to the value they currently have. This prevents leaking uninitialized memory to | 
| 416 |  |     /// the final archive. | 
| 417 |  |     /// | 
| 418 |  |     /// # Safety | 
| 419 |  |     /// | 
| 420 |  |     /// - `pos` must be the position of `out` within the archive | 
| 421 |  |     /// - `resolver` must be the result of serializing this object | 
| 422 |  |     unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived); | 
| 423 |  | } | 
| 424 |  |  | 
| 425 |  | /// Converts a type to its archived form. | 
| 426 |  | /// | 
| 427 |  | /// Objects perform any supportive serialization during [`serialize`](Serialize::serialize). For | 
| 428 |  | /// types that reference nonlocal (pointed-to) data, this is when that data must be serialized to | 
| 429 |  | /// the output. These types will need to bound `S` to implement [`Serializer`](ser::Serializer) and | 
| 430 |  | /// any other required traits (e.g. [`SharedSerializeRegistry`](ser::SharedSerializeRegistry)). They | 
| 431 |  | /// should then serialize their dependencies during `serialize`. | 
| 432 |  | /// | 
| 433 |  | /// See [`Archive`] for examples of implementing `Serialize`. | 
| 434 |  | pub trait Serialize<S: Fallible + ?Sized>: Archive { | 
| 435 |  |     /// Writes the dependencies for the object and returns a resolver that can create the archived | 
| 436 |  |     /// type. | 
| 437 |  |     fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error>; | 
| 438 |  | } | 
| 439 |  |  | 
| 440 |  | /// Converts a type back from its archived form. | 
| 441 |  | /// | 
| 442 |  | /// Some types may require specific deserializer capabilities, such as `Rc` and `Arc`. In these | 
| 443 |  | /// cases, the deserializer type `D` should be bound so that it implements traits that provide those | 
| 444 |  | /// capabilities (e.g. [`SharedDeserializeRegistry`](de::SharedDeserializeRegistry)). | 
| 445 |  | /// | 
| 446 |  | /// This can be derived with [`Deserialize`](macro@Deserialize). | 
| 447 |  | pub trait Deserialize<T, D: Fallible + ?Sized> { | 
| 448 |  |     /// Deserializes using the given deserializer | 
| 449 |  |     fn deserialize(&self, deserializer: &mut D) -> Result<T, D::Error>; | 
| 450 |  | } | 
| 451 |  |  | 
| 452 |  | /// A counterpart of [`Archive`] that's suitable for unsized types. | 
| 453 |  | /// | 
| 454 |  | /// Unlike `Archive`, types that implement `ArchiveUnsized` must be serialized separately from their | 
| 455 |  | /// owning object. For example, whereas an `i32` might be laid out as part of a larger struct, a | 
| 456 |  | /// `Box<i32>` would serialize the `i32` somewhere in the archive and the `Box` would point to it as | 
| 457 |  | /// part of the larger struct. Because of this, the equivalent [`Resolver`](Archive::Resolver) type | 
| 458 |  | /// for `ArchiveUnsized` is always a `usize` representing the position of the serialized value. | 
| 459 |  | /// | 
| 460 |  | /// `ArchiveUnsized` is automatically implemented for all types that implement [`Archive`]. Nothing | 
| 461 |  | /// special needs to be done to use them with types like `Box`, `Rc`, and `Arc`. It is also already | 
| 462 |  | /// implemented for slices and string slices, and the `rkyv_dyn` crate can be used to archive trait | 
| 463 |  | /// objects. Other unsized types must manually implement `ArchiveUnsized`. | 
| 464 |  | /// | 
| 465 |  | /// # Examples | 
| 466 |  | /// | 
| 467 |  | /// This example shows how to manually implement `ArchiveUnsized` for an unsized type. Special care | 
| 468 |  | /// must be taken to ensure that the types are laid out correctly. | 
| 469 |  | /// | 
| 470 |  | /// ``` | 
| 471 |  | /// use core::{mem::transmute, ops::{Deref, DerefMut}}; | 
| 472 |  | /// use ptr_meta::Pointee; | 
| 473 |  | /// use rkyv::{ | 
| 474 |  | ///     from_archived, | 
| 475 |  | ///     to_archived, | 
| 476 |  | ///     archived_unsized_value, | 
| 477 |  | ///     ser::{serializers::AlignedSerializer, Serializer}, | 
| 478 |  | ///     AlignedVec, | 
| 479 |  | ///     Archive, | 
| 480 |  | ///     Archived, | 
| 481 |  | ///     ArchivedMetadata, | 
| 482 |  | ///     ArchivePointee, | 
| 483 |  | ///     ArchiveUnsized, | 
| 484 |  | ///     FixedUsize, | 
| 485 |  | ///     RelPtr, | 
| 486 |  | ///     Serialize, | 
| 487 |  | ///     SerializeUnsized, | 
| 488 |  | /// }; | 
| 489 |  | /// | 
| 490 |  | /// // We're going to be dealing mostly with blocks that have a trailing slice | 
| 491 |  | /// pub struct Block<H, T: ?Sized> { | 
| 492 |  | ///     head: H, | 
| 493 |  | ///     tail: T, | 
| 494 |  | /// } | 
| 495 |  | /// | 
| 496 |  | /// impl<H, T> Pointee for Block<H, [T]> { | 
| 497 |  | ///     type Metadata = usize; | 
| 498 |  | /// } | 
| 499 |  | /// | 
| 500 |  | /// // For blocks with trailing slices, we need to store the length of the slice | 
| 501 |  | /// // in the metadata. | 
| 502 |  | /// pub struct BlockSliceMetadata { | 
| 503 |  | ///     len: Archived<usize>, | 
| 504 |  | /// } | 
| 505 |  | /// | 
| 506 |  | /// // ArchivePointee is automatically derived for sized types because pointers | 
| 507 |  | /// // to sized types don't need to store any extra information. Because we're | 
| 508 |  | /// // making an unsized block, we need to define what metadata gets stored with | 
| 509 |  | /// // our data pointer. | 
| 510 |  | /// impl<H, T> ArchivePointee for Block<H, [T]> { | 
| 511 |  | ///     // This is the extra data that needs to get stored for blocks with | 
| 512 |  | ///     // trailing slices | 
| 513 |  | ///     type ArchivedMetadata = BlockSliceMetadata; | 
| 514 |  | /// | 
| 515 |  | ///     // We need to be able to turn our archived metadata into regular | 
| 516 |  | ///     // metadata for our type | 
| 517 |  | ///     fn pointer_metadata( | 
| 518 |  | ///         archived: &Self::ArchivedMetadata | 
| 519 |  | ///     ) -> <Self as Pointee>::Metadata { | 
| 520 |  | ///         from_archived!(archived.len) as usize | 
| 521 |  | ///     } | 
| 522 |  | /// } | 
| 523 |  | /// | 
| 524 |  | /// // We're implementing ArchiveUnsized for just Block<H, [T]>. We can still | 
| 525 |  | /// // implement Archive for blocks with sized tails and they won't conflict. | 
| 526 |  | /// impl<H: Archive, T: Archive> ArchiveUnsized for Block<H, [T]> { | 
| 527 |  | ///     // We'll reuse our block type as our archived type. | 
| 528 |  | ///     type Archived = Block<Archived<H>, [Archived<T>]>; | 
| 529 |  | /// | 
| 530 |  | ///     // This is where we'd put any resolve data for our metadata. | 
| 531 |  | ///     // Most of the time, this can just be () because most metadata is Copy, | 
| 532 |  | ///     // but the option is there if you need it. | 
| 533 |  | ///     type MetadataResolver = (); | 
| 534 |  | /// | 
| 535 |  | ///     // Here's where we make the metadata for our pointer. | 
| 536 |  | ///     // This also gets the position and resolver for the metadata, but we | 
| 537 |  | ///     // don't need it in this case. | 
| 538 |  | ///     unsafe fn resolve_metadata( | 
| 539 |  | ///         &self, | 
| 540 |  | ///         _: usize, | 
| 541 |  | ///         _: Self::MetadataResolver, | 
| 542 |  | ///         out: *mut ArchivedMetadata<Self>, | 
| 543 |  | ///     ) { | 
| 544 |  | ///         unsafe { | 
| 545 |  | ///             out.write(BlockSliceMetadata { | 
| 546 |  | ///                 len: to_archived!(self.tail.len() as FixedUsize), | 
| 547 |  | ///             }); | 
| 548 |  | ///         } | 
| 549 |  | ///     } | 
| 550 |  | /// } | 
| 551 |  | /// | 
| 552 |  | /// // The bounds we use on our serializer type indicate that we need basic | 
| 553 |  | /// // serializer capabilities, and then whatever capabilities our head and tail | 
| 554 |  | /// // types need to serialize themselves. | 
| 555 |  | /// impl< | 
| 556 |  | ///     H: Serialize<S>, | 
| 557 |  | ///     T: Serialize<S>, | 
| 558 |  | ///     S: Serializer + ?Sized | 
| 559 |  | /// > SerializeUnsized<S> for Block<H, [T]> { | 
| 560 |  | ///     // This is where we construct our unsized type in the serializer | 
| 561 |  | ///     fn serialize_unsized( | 
| 562 |  | ///         &self, | 
| 563 |  | ///         serializer: &mut S | 
| 564 |  | ///     ) -> Result<usize, S::Error> { | 
| 565 |  | ///         // First, we archive the head and all the tails. This will make sure | 
| 566 |  | ///         // that when we finally build our block, we don't accidentally mess | 
| 567 |  | ///         // up the structure with serialized dependencies. | 
| 568 |  | ///         let head_resolver = self.head.serialize(serializer)?; | 
| 569 |  | ///         let mut resolvers = Vec::new(); | 
| 570 |  | ///         for tail in self.tail.iter() { | 
| 571 |  | ///             resolvers.push(tail.serialize(serializer)?); | 
| 572 |  | ///         } | 
| 573 |  | ///         // Now we align our serializer for our archived type and write it. | 
| 574 |  | ///         // We can't align for unsized types so we treat the trailing slice | 
| 575 |  | ///         // like an array of 0 length for now. | 
| 576 |  | ///         serializer.align_for::<Block<Archived<H>, [Archived<T>; 0]>>()?; | 
| 577 |  | ///         let result = unsafe { | 
| 578 |  | ///             serializer.resolve_aligned(&self.head, head_resolver)? | 
| 579 |  | ///         }; | 
| 580 |  | ///         serializer.align_for::<Archived<T>>()?; | 
| 581 |  | ///         for (item, resolver) in self.tail.iter().zip(resolvers.drain(..)) { | 
| 582 |  | ///             unsafe { | 
| 583 |  | ///                 serializer.resolve_aligned(item, resolver)?; | 
| 584 |  | ///             } | 
| 585 |  | ///         } | 
| 586 |  | ///         Ok(result) | 
| 587 |  | ///     } | 
| 588 |  | /// | 
| 589 |  | ///     // This is where we serialize the metadata for our type. In this case, | 
| 590 |  | ///     // we do all the work in resolve and don't need to do anything here. | 
| 591 |  | ///     fn serialize_metadata( | 
| 592 |  | ///         &self, | 
| 593 |  | ///         serializer: &mut S | 
| 594 |  | ///     ) -> Result<Self::MetadataResolver, S::Error> { | 
| 595 |  | ///         Ok(()) | 
| 596 |  | ///     } | 
| 597 |  | /// } | 
| 598 |  | /// | 
| 599 |  | /// let value = Block { | 
| 600 |  | ///     head: "Numbers 1-4".to_string(), | 
| 601 |  | ///     tail: [1, 2, 3, 4], | 
| 602 |  | /// }; | 
| 603 |  | /// // We have a Block<String, [i32; 4]> but we want to it to be a | 
| 604 |  | /// // Block<String, [i32]>, so we need to do more pointer transmutation | 
| 605 |  | /// let ptr = (&value as *const Block<String, [i32; 4]>).cast::<()>(); | 
| 606 |  | /// let unsized_value = unsafe { | 
| 607 |  | ///     &*transmute::<(*const (), usize), *const Block<String, [i32]>>((ptr, 4)) | 
| 608 |  | /// }; | 
| 609 |  | /// | 
| 610 |  | /// let mut serializer = AlignedSerializer::new(AlignedVec::new()); | 
| 611 |  | /// let pos = serializer.serialize_unsized_value(unsized_value) | 
| 612 |  | ///     .expect("failed to archive block"); | 
| 613 |  | /// let buf = serializer.into_inner(); | 
| 614 |  | /// | 
| 615 |  | /// let archived_ref = unsafe { | 
| 616 |  | ///     archived_unsized_value::<Block<String, [i32]>>(buf.as_slice(), pos) | 
| 617 |  | /// }; | 
| 618 |  | /// assert_eq!(archived_ref.head, "Numbers 1-4"); | 
| 619 |  | /// assert_eq!(archived_ref.tail.len(), 4); | 
| 620 |  | /// assert_eq!(archived_ref.tail, [1, 2, 3, 4]); | 
| 621 |  | /// ``` | 
| 622 |  | pub trait ArchiveUnsized: Pointee { | 
| 623 |  |     /// The archived counterpart of this type. Unlike `Archive`, it may be unsized. | 
| 624 |  |     /// | 
| 625 |  |     /// This type must implement [`ArchivePointee`], a trait that helps make valid pointers using | 
| 626 |  |     /// archived pointer metadata. | 
| 627 |  |     type Archived: ArchivePointee + ?Sized; | 
| 628 |  |  | 
| 629 |  |     /// The resolver for the metadata of this type. | 
| 630 |  |     /// | 
| 631 |  |     /// Because the pointer metadata must be archived with the relative pointer and not with the | 
| 632 |  |     /// structure itself, its resolver must be passed back to the structure holding the pointer. | 
| 633 |  |     type MetadataResolver; | 
| 634 |  |  | 
| 635 |  |     /// Creates the archived version of the metadata for this value at the given position and writes | 
| 636 |  |     /// it to the given output. | 
| 637 |  |     /// | 
| 638 |  |     /// The output should be initialized field-by-field rather than by writing a whole struct. | 
| 639 |  |     /// Performing a typed copy will mark all of the padding bytes as uninitialized, but they must | 
| 640 |  |     /// remain set to the value they currently have. This prevents leaking uninitialized memory to | 
| 641 |  |     /// the final archive. | 
| 642 |  |     /// | 
| 643 |  |     /// # Safety | 
| 644 |  |     /// | 
| 645 |  |     /// - `pos` must be the position of `out` within the archive | 
| 646 |  |     /// - `resolver` must be the result of serializing this object's metadata | 
| 647 |  |     unsafe fn resolve_metadata( | 
| 648 |  |         &self, | 
| 649 |  |         pos: usize, | 
| 650 |  |         resolver: Self::MetadataResolver, | 
| 651 |  |         out: *mut ArchivedMetadata<Self>, | 
| 652 |  |     ); | 
| 653 |  |  | 
| 654 |  |     /// Resolves a relative pointer to this value with the given `from` and `to` and writes it to | 
| 655 |  |     /// the given output. | 
| 656 |  |     /// | 
| 657 |  |     /// The output should be initialized field-by-field rather than by writing a whole struct. | 
| 658 |  |     /// Performing a typed copy will mark all of the padding bytes as uninitialized, but they must | 
| 659 |  |     /// remain set to the value they currently have. This prevents leaking uninitialized memory to | 
| 660 |  |     /// the final archive. | 
| 661 |  |     /// | 
| 662 |  |     /// # Safety | 
| 663 |  |     /// | 
| 664 |  |     /// - `from` must be the position of `out` within the archive | 
| 665 |  |     /// - `to` must be the position of some `Self::Archived` within the archive | 
| 666 |  |     /// - `resolver` must be the result of serializing this object | 
| 667 |  |     #[inline] | 
| 668 | 511k |     unsafe fn resolve_unsized( | 
| 669 | 511k |         &self, | 
| 670 | 511k |         from: usize, | 
| 671 | 511k |         to: usize, | 
| 672 | 511k |         resolver: Self::MetadataResolver, | 
| 673 | 511k |         out: *mut RelPtr<Self::Archived>, | 
| 674 | 511k |     ) { | 
| 675 | 511k |         RelPtr::resolve_emplace(from, to, self, resolver, out); | 
| 676 | 511k |     } <wasmer_types::module::ModuleInfo as rkyv::ArchiveUnsized>::resolve_unsized| Line | Count | Source |  | 668 | 30.0k |     unsafe fn resolve_unsized( |  | 669 | 30.0k |         &self, |  | 670 | 30.0k |         from: usize, |  | 671 | 30.0k |         to: usize, |  | 672 | 30.0k |         resolver: Self::MetadataResolver, |  | 673 | 30.0k |         out: *mut RelPtr<Self::Archived>, |  | 674 | 30.0k |     ) { |  | 675 | 30.0k |         RelPtr::resolve_emplace(from, to, self, resolver, out); |  | 676 | 30.0k |     } | 
<[wasmer_types::initializers::OwnedDataInitializer] as rkyv::ArchiveUnsized>::resolve_unsized| Line | Count | Source |  | 668 | 30.0k |     unsafe fn resolve_unsized( |  | 669 | 30.0k |         &self, |  | 670 | 30.0k |         from: usize, |  | 671 | 30.0k |         to: usize, |  | 672 | 30.0k |         resolver: Self::MetadataResolver, |  | 673 | 30.0k |         out: *mut RelPtr<Self::Archived>, |  | 674 | 30.0k |     ) { |  | 675 | 30.0k |         RelPtr::resolve_emplace(from, to, self, resolver, out); |  | 676 | 30.0k |     } | 
<[wasmer_types::types::Type] as rkyv::ArchiveUnsized>::resolve_unsized| Line | Count | Source |  | 668 | 309k |     unsafe fn resolve_unsized( |  | 669 | 309k |         &self, |  | 670 | 309k |         from: usize, |  | 671 | 309k |         to: usize, |  | 672 | 309k |         resolver: Self::MetadataResolver, |  | 673 | 309k |         out: *mut RelPtr<Self::Archived>, |  | 674 | 309k |     ) { |  | 675 | 309k |         RelPtr::resolve_emplace(from, to, self, resolver, out); |  | 676 | 309k |     } | 
<[wasmer_types::indexes::FunctionIndex] as rkyv::ArchiveUnsized>::resolve_unsized| Line | Count | Source |  | 668 | 84.5k |     unsafe fn resolve_unsized( |  | 669 | 84.5k |         &self, |  | 670 | 84.5k |         from: usize, |  | 671 | 84.5k |         to: usize, |  | 672 | 84.5k |         resolver: Self::MetadataResolver, |  | 673 | 84.5k |         out: *mut RelPtr<Self::Archived>, |  | 674 | 84.5k |     ) { |  | 675 | 84.5k |         RelPtr::resolve_emplace(from, to, self, resolver, out); |  | 676 | 84.5k |     } | 
<[u8] as rkyv::ArchiveUnsized>::resolve_unsized| Line | Count | Source |  | 668 | 57.0k |     unsafe fn resolve_unsized( |  | 669 | 57.0k |         &self, |  | 670 | 57.0k |         from: usize, |  | 671 | 57.0k |         to: usize, |  | 672 | 57.0k |         resolver: Self::MetadataResolver, |  | 673 | 57.0k |         out: *mut RelPtr<Self::Archived>, |  | 674 | 57.0k |     ) { |  | 675 | 57.0k |         RelPtr::resolve_emplace(from, to, self, resolver, out); |  | 676 | 57.0k |     } | 
Unexecuted instantiation: <core::ffi::c_str::CStr as rkyv::ArchiveUnsized>::resolve_unsizedUnexecuted instantiation: <str as rkyv::ArchiveUnsized>::resolve_unsizedUnexecuted instantiation: <wasmer_types::module::ModuleInfo as rkyv::ArchiveUnsized>::resolve_unsizedUnexecuted instantiation: <[wasmer_types::initializers::OwnedDataInitializer] as rkyv::ArchiveUnsized>::resolve_unsizedUnexecuted instantiation: <[wasmer_types::types::Type] as rkyv::ArchiveUnsized>::resolve_unsizedUnexecuted instantiation: <[wasmer_types::indexes::FunctionIndex] as rkyv::ArchiveUnsized>::resolve_unsizedUnexecuted instantiation: <[u8] as rkyv::ArchiveUnsized>::resolve_unsizedUnexecuted instantiation: <core::ffi::c_str::CStr as rkyv::ArchiveUnsized>::resolve_unsizedUnexecuted instantiation: <str as rkyv::ArchiveUnsized>::resolve_unsized | 
| 677 |  | } | 
| 678 |  |  | 
| 679 |  | /// An archived type with associated metadata for its relative pointer. | 
| 680 |  | /// | 
| 681 |  | /// This is mostly used in the context of smart pointers and unsized types, and is implemented for | 
| 682 |  | /// all sized types by default. | 
| 683 |  | pub trait ArchivePointee: Pointee { | 
| 684 |  |     /// The archived version of the pointer metadata for this type. | 
| 685 |  |     type ArchivedMetadata; | 
| 686 |  |  | 
| 687 |  |     /// Converts some archived metadata to the pointer metadata for itself. | 
| 688 |  |     fn pointer_metadata(archived: &Self::ArchivedMetadata) -> <Self as Pointee>::Metadata; | 
| 689 |  | } | 
| 690 |  |  | 
| 691 |  | /// A counterpart of [`Serialize`] that's suitable for unsized types. | 
| 692 |  | /// | 
| 693 |  | /// See [`ArchiveUnsized`] for examples of implementing `SerializeUnsized`. | 
| 694 |  | pub trait SerializeUnsized<S: Fallible + ?Sized>: ArchiveUnsized { | 
| 695 |  |     /// Writes the object and returns the position of the archived type. | 
| 696 |  |     fn serialize_unsized(&self, serializer: &mut S) -> Result<usize, S::Error>; | 
| 697 |  |  | 
| 698 |  |     /// Serializes the metadata for the given type. | 
| 699 |  |     fn serialize_metadata(&self, serializer: &mut S) -> Result<Self::MetadataResolver, S::Error>; | 
| 700 |  | } | 
| 701 |  |  | 
| 702 |  | /// A counterpart of [`Deserialize`] that's suitable for unsized types. | 
| 703 |  | pub trait DeserializeUnsized<T: Pointee + ?Sized, D: Fallible + ?Sized>: ArchivePointee { | 
| 704 |  |     /// Deserializes a reference to the given value. | 
| 705 |  |     /// | 
| 706 |  |     /// # Safety | 
| 707 |  |     /// | 
| 708 |  |     /// `out` must point to memory with the layout returned by `deserialized_layout`. | 
| 709 |  |     unsafe fn deserialize_unsized( | 
| 710 |  |         &self, | 
| 711 |  |         deserializer: &mut D, | 
| 712 |  |         alloc: impl FnMut(Layout) -> *mut u8, | 
| 713 |  |     ) -> Result<*mut (), D::Error>; | 
| 714 |  |  | 
| 715 |  |     /// Deserializes the metadata for the given type. | 
| 716 |  |     fn deserialize_metadata(&self, deserializer: &mut D) -> Result<T::Metadata, D::Error>; | 
| 717 |  | } | 
| 718 |  |  | 
| 719 |  | /// The native type that `usize` is converted to for archiving. | 
| 720 |  | /// | 
| 721 |  | /// This will be `u16`, `u32`, or `u64` when the `size_16`, `size_32`, or `size_64` features are | 
| 722 |  | /// enabled, respectively. | 
| 723 |  | pub type FixedUsize = pick_size_type!(u16, u32, u64); | 
| 724 |  | /// The native type that `isize` is converted to for archiving. | 
| 725 |  | /// | 
| 726 |  | /// This will be `i16`, `i32`, or `i64` when the `size_16`, `size_32`, or `size_64` features are | 
| 727 |  | /// enabled, respectively. | 
| 728 |  | pub type FixedIsize = pick_size_type!(i16, i32, i64); | 
| 729 |  |  | 
| 730 |  | /// The default raw relative pointer. | 
| 731 |  | /// | 
| 732 |  | /// This will use an archived [`FixedIsize`] to hold the offset. | 
| 733 |  | pub type RawRelPtr = rel_ptr::RawRelPtr<Archived<isize>>; | 
| 734 |  | /// The default relative pointer. | 
| 735 |  | /// | 
| 736 |  | /// This will use an archived [`FixedIsize`] to hold the offset. | 
| 737 |  | pub type RelPtr<T> = rel_ptr::RelPtr<T, Archived<isize>>; | 
| 738 |  |  | 
| 739 |  | /// Alias for the archived version of some [`Archive`] type. | 
| 740 |  | /// | 
| 741 |  | /// This can be useful for reducing the lengths of type definitions. | 
| 742 |  | pub type Archived<T> = <T as Archive>::Archived; | 
| 743 |  | /// Alias for the resolver for some [`Archive`] type. | 
| 744 |  | /// | 
| 745 |  | /// This can be useful for reducing the lengths of type definitions. | 
| 746 |  | pub type Resolver<T> = <T as Archive>::Resolver; | 
| 747 |  | /// Alias for the archived metadata for some [`ArchiveUnsized`] type. | 
| 748 |  | /// | 
| 749 |  | /// This can be useful for reducing the lengths of type definitions. | 
| 750 |  | pub type ArchivedMetadata<T> = | 
| 751 |  |     <<T as ArchiveUnsized>::Archived as ArchivePointee>::ArchivedMetadata; | 
| 752 |  | /// Alias for the metadata resolver for some [`ArchiveUnsized`] type. | 
| 753 |  | /// | 
| 754 |  | /// This can be useful for reducing the lengths of type definitions. | 
| 755 |  | pub type MetadataResolver<T> = <T as ArchiveUnsized>::MetadataResolver; |