rkyv_test/
lib.rs

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//! - `tinyvec_alloc`: Supports types behind the `alloc` feature in `tinyvec`.
100//! - `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
135#[cfg(all(feature = "alloc", not(feature = "std")))]
136extern crate alloc;
137#[cfg(feature = "std")]
138extern crate std;
139
140#[doc(hidden)]
141#[macro_use]
142pub mod macros;
143
144pub mod boxed;
145pub mod collections;
146#[cfg(feature = "copy")]
147pub mod copy;
148pub mod de;
149// This is pretty unfortunate. CStr doesn't rely on the rest of std, but it's not in core.
150// If CStr ever gets moved into `core` then this module will no longer need cfg(feature = "std")
151#[cfg(feature = "std")]
152pub mod ffi;
153mod impls;
154pub mod net;
155pub mod niche;
156pub mod ops;
157pub mod option;
158pub mod rc;
159pub mod rel_ptr;
160pub mod result;
161pub mod ser;
162pub mod string;
163pub mod time;
164pub mod util;
165#[cfg(feature = "validation")]
166pub mod validation;
167pub mod vec;
168pub mod with;
169
170#[cfg(feature = "rend")]
171pub use rend;
172
173use core::alloc::Layout;
174use ptr_meta::Pointee;
175pub use rkyv_derive::{Archive, Deserialize, Serialize};
176pub use util::*;
177#[cfg(feature = "validation")]
178#[cfg_attr(doc_cfg, doc(cfg(feature = "validation")))]
179pub use validation::{
180    check_archived_root_with_context, check_archived_value_with_context,
181    validators::{check_archived_root, check_archived_value, from_bytes},
182};
183
184/// A type that can produce an error.
185///
186/// This trait is always implemented by serializers and deserializers. Its purpose is to provide an
187/// error type without restricting what other capabilities the type must provide.
188///
189/// When writing implementations for [`Serialize`] and [`Deserialize`], it's best practice to bound
190/// the serializer or deserializer by `Fallible` and then require that the serialized types support
191/// it (i.e. `S: Fallible, MyType: Serialize<S>`).
192pub trait Fallible {
193    /// The error produced by any failing methods.
194    type Error: 'static;
195}
196
197/// A fallible type that cannot produce errors.
198///
199/// This type can be used to serialize and deserialize types that cannot fail to serialize or
200/// deserialize.
201#[derive(Debug)]
202pub struct Infallible;
203
204impl Fallible for Infallible {
205    type Error = core::convert::Infallible;
206}
207
208impl Default for Infallible {
209    fn default() -> Self {
210        Infallible
211    }
212}
213
214/// A type that can be used without deserializing.
215///
216/// `Archive` is one of three basic traits used to work with zero-copy data and controls the layout
217/// of the data in its archived zero-copy representation. The [`Serialize`] trait helps transform
218/// types into that representation, and the [`Deserialize`] trait helps transform types back out.
219///
220/// Types that implement `Archive` must have a well-defined archived size. Unsized types can be
221/// supported using the [`ArchiveUnsized`] trait, along with [`SerializeUnsized`] and
222/// [`DeserializeUnsized`].
223///
224/// Archiving is done depth-first, writing any data owned by a type before writing the data for the
225/// type itself. The type must be able to create the archived type from only its own data and its
226/// resolver.
227///
228/// Archived data is always treated as if it is tree-shaped, with the root owning its direct
229/// descendents and so on. Data that is not tree-shaped can be supported using special serializer
230/// and deserializer bounds (see [`ArchivedRc`](crate::rc::ArchivedRc) for example). In a buffer of
231/// serialized data, objects are laid out in *reverse order*. This means that the root object is
232/// located near the end of the buffer and leaf objects are located near the beginning.
233///
234/// # Examples
235///
236/// Most of the time, `#[derive(Archive)]` will create an acceptable implementation. You can use the
237/// `#[archive(...)]` and `#[archive_attr(...)]` attributes to control how the implementation is
238/// generated. See the [`Archive`](macro@Archive) derive macro for more details.
239///
240/// ```
241/// use rkyv::{Archive, Deserialize, Serialize};
242///
243/// #[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
244/// // This will generate a PartialEq impl between our unarchived and archived types
245/// #[archive(compare(PartialEq))]
246/// // We can pass attributes through to generated types with archive_attr
247/// #[archive_attr(derive(Debug))]
248/// struct Test {
249///     int: u8,
250///     string: String,
251///     option: Option<Vec<i32>>,
252/// }
253///
254/// let value = Test {
255///     int: 42,
256///     string: "hello world".to_string(),
257///     option: Some(vec![1, 2, 3, 4]),
258/// };
259///
260/// // Serializing is as easy as a single function call
261/// let bytes = rkyv::to_bytes::<_, 256>(&value).unwrap();
262///
263/// // Or you can customize your serialization for better performance
264/// // and compatibility with #![no_std] environments
265/// use rkyv::ser::{Serializer, serializers::AllocSerializer};
266///
267/// let mut serializer = AllocSerializer::<0>::default();
268/// serializer.serialize_value(&value).unwrap();
269/// let bytes = serializer.into_serializer().into_inner();
270///
271/// // You can use the safe API with the validation feature turned on,
272/// // or you can use the unsafe API (shown here) for maximum performance
273/// let archived = unsafe { rkyv::archived_root::<Test>(&bytes[..]) };
274/// assert_eq!(archived, &value);
275///
276/// // And you can always deserialize back to the original type
277/// let deserialized: Test = archived.deserialize(&mut rkyv::Infallible).unwrap();
278/// assert_eq!(deserialized, value);
279/// ```
280///
281/// _Note: the safe API requires the `validation` feature._
282///
283/// Many of the core and standard library types already have `Archive` implementations available,
284/// but you may need to implement `Archive` for your own types in some cases the derive macro cannot
285/// handle.
286///
287/// In this example, we add our own wrapper that serializes a `&'static str` as if it's owned.
288/// Normally you can lean on the archived version of `String` to do most of the work, or use the
289/// [`Inline`](crate::with::Inline) to do exactly this. This example does everything to demonstrate
290/// how to implement `Archive` for your own types.
291///
292/// ```
293/// use core::{slice, str};
294/// use rkyv::{
295///     archived_root,
296///     ser::{Serializer, serializers::AlignedSerializer},
297///     out_field,
298///     AlignedVec,
299///     Archive,
300///     Archived,
301///     ArchiveUnsized,
302///     MetadataResolver,
303///     RelPtr,
304///     Serialize,
305///     SerializeUnsized,
306/// };
307///
308/// struct OwnedStr {
309///     inner: &'static str,
310/// }
311///
312/// struct ArchivedOwnedStr {
313///     // This will be a relative pointer to our string
314///     ptr: RelPtr<str>,
315/// }
316///
317/// impl ArchivedOwnedStr {
318///     // This will help us get the bytes of our type as a str again.
319///     fn as_str(&self) -> &str {
320///         unsafe {
321///             // The as_ptr() function of RelPtr will get a pointer the str
322///             &*self.ptr.as_ptr()
323///         }
324///     }
325/// }
326///
327/// struct OwnedStrResolver {
328///     // This will be the position that the bytes of our string are stored at.
329///     // We'll use this to resolve the relative pointer of our
330///     // ArchivedOwnedStr.
331///     pos: usize,
332///     // The archived metadata for our str may also need a resolver.
333///     metadata_resolver: MetadataResolver<str>,
334/// }
335///
336/// // The Archive implementation defines the archived version of our type and
337/// // determines how to turn the resolver into the archived form. The Serialize
338/// // implementations determine how to make a resolver from the original value.
339/// impl Archive for OwnedStr {
340///     type Archived = ArchivedOwnedStr;
341///     // This is the resolver we can create our Archived version from.
342///     type Resolver = OwnedStrResolver;
343///
344///     // The resolve function consumes the resolver and produces the archived
345///     // value at the given position.
346///     unsafe fn resolve(
347///         &self,
348///         pos: usize,
349///         resolver: Self::Resolver,
350///         out: *mut Self::Archived,
351///     ) {
352///         // We have to be careful to add the offset of the ptr field,
353///         // otherwise we'll be using the position of the ArchivedOwnedStr
354///         // instead of the position of the relative pointer.
355///         let (fp, fo) = out_field!(out.ptr);
356///         self.inner.resolve_unsized(
357///             pos + fp,
358///             resolver.pos,
359///             resolver.metadata_resolver,
360///             fo,
361///         );
362///     }
363/// }
364///
365/// // We restrict our serializer types with Serializer because we need its
366/// // capabilities to archive our type. For other types, we might need more or
367/// // less restrictive bounds on the type of S.
368/// impl<S: Serializer + ?Sized> Serialize<S> for OwnedStr {
369///     fn serialize(
370///         &self,
371///         serializer: &mut S
372///     ) -> Result<Self::Resolver, S::Error> {
373///         // This is where we want to write the bytes of our string and return
374///         // a resolver that knows where those bytes were written.
375///         // We also need to serialize the metadata for our str.
376///         Ok(OwnedStrResolver {
377///             pos: self.inner.serialize_unsized(serializer)?,
378///             metadata_resolver: self.inner.serialize_metadata(serializer)?
379///         })
380///     }
381/// }
382///
383/// let mut serializer = AlignedSerializer::new(AlignedVec::new());
384/// const STR_VAL: &'static str = "I'm in an OwnedStr!";
385/// let value = OwnedStr { inner: STR_VAL };
386/// // It works!
387/// serializer.serialize_value(&value).expect("failed to archive test");
388/// let buf = serializer.into_inner();
389/// let archived = unsafe { archived_root::<OwnedStr>(buf.as_ref()) };
390/// // Let's make sure our data got written correctly
391/// assert_eq!(archived.as_str(), STR_VAL);
392/// ```
393pub trait Archive {
394    /// The archived representation of this type.
395    ///
396    /// In this form, the data can be used with zero-copy deserialization.
397    type Archived;
398
399    /// The resolver for this type. It must contain all the additional information from serializing
400    /// needed to make the archived type from the normal type.
401    type Resolver;
402
403    /// Creates the archived version of this value at the given position and writes it to the given
404    /// output.
405    ///
406    /// The output should be initialized field-by-field rather than by writing a whole struct.
407    /// Performing a typed copy will mark all of the padding bytes as uninitialized, but they must
408    /// remain set to the value they currently have. This prevents leaking uninitialized memory to
409    /// the final archive.
410    ///
411    /// # Safety
412    ///
413    /// - `pos` must be the position of `out` within the archive
414    /// - `resolver` must be the result of serializing this object
415    unsafe fn resolve(&self, pos: usize, resolver: Self::Resolver, out: *mut Self::Archived);
416}
417
418/// Converts a type to its archived form.
419///
420/// Objects perform any supportive serialization during [`serialize`](Serialize::serialize). For
421/// types that reference nonlocal (pointed-to) data, this is when that data must be serialized to
422/// the output. These types will need to bound `S` to implement [`Serializer`](ser::Serializer) and
423/// any other required traits (e.g. [`SharedSerializeRegistry`](ser::SharedSerializeRegistry)). They
424/// should then serialize their dependencies during `serialize`.
425///
426/// See [`Archive`] for examples of implementing `Serialize`.
427pub trait Serialize<S: Fallible + ?Sized>: Archive {
428    /// Writes the dependencies for the object and returns a resolver that can create the archived
429    /// type.
430    fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error>;
431}
432
433/// Converts a type back from its archived form.
434///
435/// Some types may require specific deserializer capabilities, such as `Rc` and `Arc`. In these
436/// cases, the deserializer type `D` should be bound so that it implements traits that provide those
437/// capabilities (e.g. [`SharedDeserializeRegistry`](de::SharedDeserializeRegistry)).
438///
439/// This can be derived with [`Deserialize`](macro@Deserialize).
440pub trait Deserialize<T, D: Fallible + ?Sized> {
441    /// Deserializes using the given deserializer
442    fn deserialize(&self, deserializer: &mut D) -> Result<T, D::Error>;
443}
444
445/// A counterpart of [`Archive`] that's suitable for unsized types.
446///
447/// Unlike `Archive`, types that implement `ArchiveUnsized` must be serialized separately from their
448/// owning object. For example, whereas an `i32` might be laid out as part of a larger struct, a
449/// `Box<i32>` would serialize the `i32` somewhere in the archive and the `Box` would point to it as
450/// part of the larger struct. Because of this, the equivalent [`Resolver`](Archive::Resolver) type
451/// for `ArchiveUnsized` is always a `usize` representing the position of the serialized value.
452///
453/// `ArchiveUnsized` is automatically implemented for all types that implement [`Archive`]. Nothing
454/// special needs to be done to use them with types like `Box`, `Rc`, and `Arc`. It is also already
455/// implemented for slices and string slices, and the `rkyv_dyn` crate can be used to archive trait
456/// objects. Other unsized types must manually implement `ArchiveUnsized`.
457///
458/// # Examples
459///
460/// This example shows how to manually implement `ArchiveUnsized` for an unsized type. Special care
461/// must be taken to ensure that the types are laid out correctly.
462///
463/// ```
464/// use core::{mem::transmute, ops::{Deref, DerefMut}};
465/// use ptr_meta::Pointee;
466/// use rkyv::{
467///     from_archived,
468///     to_archived,
469///     archived_unsized_value,
470///     ser::{serializers::AlignedSerializer, Serializer},
471///     AlignedVec,
472///     Archive,
473///     Archived,
474///     ArchivedMetadata,
475///     ArchivePointee,
476///     ArchiveUnsized,
477///     FixedUsize,
478///     RelPtr,
479///     Serialize,
480///     SerializeUnsized,
481/// };
482///
483/// // We're going to be dealing mostly with blocks that have a trailing slice
484/// pub struct Block<H, T: ?Sized> {
485///     head: H,
486///     tail: T,
487/// }
488///
489/// impl<H, T> Pointee for Block<H, [T]> {
490///     type Metadata = usize;
491/// }
492///
493/// // For blocks with trailing slices, we need to store the length of the slice
494/// // in the metadata.
495/// pub struct BlockSliceMetadata {
496///     len: Archived<usize>,
497/// }
498///
499/// // ArchivePointee is automatically derived for sized types because pointers
500/// // to sized types don't need to store any extra information. Because we're
501/// // making an unsized block, we need to define what metadata gets stored with
502/// // our data pointer.
503/// impl<H, T> ArchivePointee for Block<H, [T]> {
504///     // This is the extra data that needs to get stored for blocks with
505///     // trailing slices
506///     type ArchivedMetadata = BlockSliceMetadata;
507///
508///     // We need to be able to turn our archived metadata into regular
509///     // metadata for our type
510///     fn pointer_metadata(
511///         archived: &Self::ArchivedMetadata
512///     ) -> <Self as Pointee>::Metadata {
513///         from_archived!(archived.len) as usize
514///     }
515/// }
516///
517/// // We're implementing ArchiveUnsized for just Block<H, [T]>. We can still
518/// // implement Archive for blocks with sized tails and they won't conflict.
519/// impl<H: Archive, T: Archive> ArchiveUnsized for Block<H, [T]> {
520///     // We'll reuse our block type as our archived type.
521///     type Archived = Block<Archived<H>, [Archived<T>]>;
522///
523///     // This is where we'd put any resolve data for our metadata.
524///     // Most of the time, this can just be () because most metadata is Copy,
525///     // but the option is there if you need it.
526///     type MetadataResolver = ();
527///
528///     // Here's where we make the metadata for our pointer.
529///     // This also gets the position and resolver for the metadata, but we
530///     // don't need it in this case.
531///     unsafe fn resolve_metadata(
532///         &self,
533///         _: usize,
534///         _: Self::MetadataResolver,
535///         out: *mut ArchivedMetadata<Self>,
536///     ) {
537///         unsafe {
538///             out.write(BlockSliceMetadata {
539///                 len: to_archived!(self.tail.len() as FixedUsize),
540///             });
541///         }
542///     }
543/// }
544///
545/// // The bounds we use on our serializer type indicate that we need basic
546/// // serializer capabilities, and then whatever capabilities our head and tail
547/// // types need to serialize themselves.
548/// impl<
549///     H: Serialize<S>,
550///     T: Serialize<S>,
551///     S: Serializer + ?Sized
552/// > SerializeUnsized<S> for Block<H, [T]> {
553///     // This is where we construct our unsized type in the serializer
554///     fn serialize_unsized(
555///         &self,
556///         serializer: &mut S
557///     ) -> Result<usize, S::Error> {
558///         // First, we archive the head and all the tails. This will make sure
559///         // that when we finally build our block, we don't accidentally mess
560///         // up the structure with serialized dependencies.
561///         let head_resolver = self.head.serialize(serializer)?;
562///         let mut resolvers = Vec::new();
563///         for tail in self.tail.iter() {
564///             resolvers.push(tail.serialize(serializer)?);
565///         }
566///         // Now we align our serializer for our archived type and write it.
567///         // We can't align for unsized types so we treat the trailing slice
568///         // like an array of 0 length for now.
569///         serializer.align_for::<Block<Archived<H>, [Archived<T>; 0]>>()?;
570///         let result = unsafe {
571///             serializer.resolve_aligned(&self.head, head_resolver)?
572///         };
573///         serializer.align_for::<Archived<T>>()?;
574///         for (item, resolver) in self.tail.iter().zip(resolvers.drain(..)) {
575///             unsafe {
576///                 serializer.resolve_aligned(item, resolver)?;
577///             }
578///         }
579///         Ok(result)
580///     }
581///
582///     // This is where we serialize the metadata for our type. In this case,
583///     // we do all the work in resolve and don't need to do anything here.
584///     fn serialize_metadata(
585///         &self,
586///         serializer: &mut S
587///     ) -> Result<Self::MetadataResolver, S::Error> {
588///         Ok(())
589///     }
590/// }
591///
592/// let value = Block {
593///     head: "Numbers 1-4".to_string(),
594///     tail: [1, 2, 3, 4],
595/// };
596/// // We have a Block<String, [i32; 4]> but we want to it to be a
597/// // Block<String, [i32]>, so we need to do more pointer transmutation
598/// let ptr = (&value as *const Block<String, [i32; 4]>).cast::<()>();
599/// let unsized_value = unsafe {
600///     &*transmute::<(*const (), usize), *const Block<String, [i32]>>((ptr, 4))
601/// };
602///
603/// let mut serializer = AlignedSerializer::new(AlignedVec::new());
604/// let pos = serializer.serialize_unsized_value(unsized_value)
605///     .expect("failed to archive block");
606/// let buf = serializer.into_inner();
607///
608/// let archived_ref = unsafe {
609///     archived_unsized_value::<Block<String, [i32]>>(buf.as_slice(), pos)
610/// };
611/// assert_eq!(archived_ref.head, "Numbers 1-4");
612/// assert_eq!(archived_ref.tail.len(), 4);
613/// assert_eq!(archived_ref.tail, [1, 2, 3, 4]);
614/// ```
615pub trait ArchiveUnsized: Pointee {
616    /// The archived counterpart of this type. Unlike `Archive`, it may be unsized.
617    ///
618    /// This type must implement [`ArchivePointee`], a trait that helps make valid pointers using
619    /// archived pointer metadata.
620    type Archived: ArchivePointee + ?Sized;
621
622    /// The resolver for the metadata of this type.
623    ///
624    /// Because the pointer metadata must be archived with the relative pointer and not with the
625    /// structure itself, its resolver must be passed back to the structure holding the pointer.
626    type MetadataResolver;
627
628    /// Creates the archived version of the metadata for this value at the given position and writes
629    /// it to the given output.
630    ///
631    /// The output should be initialized field-by-field rather than by writing a whole struct.
632    /// Performing a typed copy will mark all of the padding bytes as uninitialized, but they must
633    /// remain set to the value they currently have. This prevents leaking uninitialized memory to
634    /// the final archive.
635    ///
636    /// # Safety
637    ///
638    /// - `pos` must be the position of `out` within the archive
639    /// - `resolver` must be the result of serializing this object's metadata
640    unsafe fn resolve_metadata(
641        &self,
642        pos: usize,
643        resolver: Self::MetadataResolver,
644        out: *mut ArchivedMetadata<Self>,
645    );
646
647    /// Resolves a relative pointer to this value with the given `from` and `to` and writes it to
648    /// the given output.
649    ///
650    /// The output should be initialized field-by-field rather than by writing a whole struct.
651    /// Performing a typed copy will mark all of the padding bytes as uninitialized, but they must
652    /// remain set to the value they currently have. This prevents leaking uninitialized memory to
653    /// the final archive.
654    ///
655    /// # Safety
656    ///
657    /// - `from` must be the position of `out` within the archive
658    /// - `to` must be the position of some `Self::Archived` within the archive
659    /// - `resolver` must be the result of serializing this object
660    #[inline]
661    unsafe fn resolve_unsized(
662        &self,
663        from: usize,
664        to: usize,
665        resolver: Self::MetadataResolver,
666        out: *mut RelPtr<Self::Archived>,
667    ) {
668        RelPtr::resolve_emplace(from, to, self, resolver, out);
669    }
670}
671
672/// An archived type with associated metadata for its relative pointer.
673///
674/// This is mostly used in the context of smart pointers and unsized types, and is implemented for
675/// all sized types by default.
676pub trait ArchivePointee: Pointee {
677    /// The archived version of the pointer metadata for this type.
678    type ArchivedMetadata;
679
680    /// Converts some archived metadata to the pointer metadata for itself.
681    fn pointer_metadata(archived: &Self::ArchivedMetadata) -> <Self as Pointee>::Metadata;
682}
683
684/// A counterpart of [`Serialize`] that's suitable for unsized types.
685///
686/// See [`ArchiveUnsized`] for examples of implementing `SerializeUnsized`.
687pub trait SerializeUnsized<S: Fallible + ?Sized>: ArchiveUnsized {
688    /// Writes the object and returns the position of the archived type.
689    fn serialize_unsized(&self, serializer: &mut S) -> Result<usize, S::Error>;
690
691    /// Serializes the metadata for the given type.
692    fn serialize_metadata(&self, serializer: &mut S) -> Result<Self::MetadataResolver, S::Error>;
693}
694
695/// A counterpart of [`Deserialize`] that's suitable for unsized types.
696pub trait DeserializeUnsized<T: Pointee + ?Sized, D: Fallible + ?Sized>: ArchivePointee {
697    /// Deserializes a reference to the given value.
698    ///
699    /// # Safety
700    ///
701    /// `out` must point to memory with the layout returned by `deserialized_layout`.
702    unsafe fn deserialize_unsized(
703        &self,
704        deserializer: &mut D,
705        alloc: impl FnMut(Layout) -> *mut u8,
706    ) -> Result<*mut (), D::Error>;
707
708    /// Deserializes the metadata for the given type.
709    fn deserialize_metadata(&self, deserializer: &mut D) -> Result<T::Metadata, D::Error>;
710}
711
712/// The native type that `usize` is converted to for archiving.
713///
714/// This will be `u16`, `u32`, or `u64` when the `size_16`, `size_32`, or `size_64` features are
715/// enabled, respectively.
716pub type FixedUsize = pick_size_type!(u16, u32, u64);
717/// The native type that `isize` is converted to for archiving.
718///
719/// This will be `i16`, `i32`, or `i64` when the `size_16`, `size_32`, or `size_64` features are
720/// enabled, respectively.
721pub type FixedIsize = pick_size_type!(i16, i32, i64);
722
723/// The default raw relative pointer.
724///
725/// This will use an archived [`FixedIsize`] to hold the offset.
726pub type RawRelPtr = rel_ptr::RawRelPtr<Archived<isize>>;
727/// The default relative pointer.
728///
729/// This will use an archived [`FixedIsize`] to hold the offset.
730pub type RelPtr<T> = rel_ptr::RelPtr<T, Archived<isize>>;
731
732/// Alias for the archived version of some [`Archive`] type.
733///
734/// This can be useful for reducing the lengths of type definitions.
735pub type Archived<T> = <T as Archive>::Archived;
736/// Alias for the resolver for some [`Archive`] type.
737///
738/// This can be useful for reducing the lengths of type definitions.
739pub type Resolver<T> = <T as Archive>::Resolver;
740/// Alias for the archived metadata for some [`ArchiveUnsized`] type.
741///
742/// This can be useful for reducing the lengths of type definitions.
743pub type ArchivedMetadata<T> =
744    <<T as ArchiveUnsized>::Archived as ArchivePointee>::ArchivedMetadata;
745/// Alias for the metadata resolver for some [`ArchiveUnsized`] type.
746///
747/// This can be useful for reducing the lengths of type definitions.
748pub type MetadataResolver<T> = <T as ArchiveUnsized>::MetadataResolver;