Skip to main content

rkyv/ser/
mod.rs

1//! Serialization traits and adapters.
2
3pub mod allocator;
4pub mod sharing;
5pub mod writer;
6
7use ::core::{alloc::Layout, ptr::NonNull};
8
9#[doc(inline)]
10pub use self::{
11    allocator::Allocator,
12    sharing::{Sharing, SharingExt},
13    writer::{Positional, Writer, WriterExt},
14};
15
16/// A serializer built from composeable pieces.
17#[derive(Debug, Default)]
18pub struct Serializer<W, A, S> {
19    /// The writer of the serializer.
20    pub writer: W,
21    /// The allocator of the serializer.
22    pub allocator: A,
23    /// The pointer sharing of the serializer.
24    pub sharing: S,
25}
26
27impl<W, A, S> Serializer<W, A, S> {
28    /// Creates a new serializer from a writer, allocator, and pointer sharing.
29    pub fn new(writer: W, allocator: A, sharing: S) -> Self {
30        Self {
31            writer,
32            allocator,
33            sharing,
34        }
35    }
36
37    /// Consumes the serializer and returns the components.
38    pub fn into_raw_parts(self) -> (W, A, S) {
39        (self.writer, self.allocator, self.sharing)
40    }
41
42    /// Consumes the serializer and returns the writer.
43    ///
44    /// The allocator and pointer sharing are discarded.
45    pub fn into_writer(self) -> W {
46        self.writer
47    }
48}
49
50impl<W: Positional, A, S> Positional for Serializer<W, A, S> {
51    fn pos(&self) -> usize {
52        self.writer.pos()
53    }
54}
55
56impl<W: Writer<E>, A, S, E> Writer<E> for Serializer<W, A, S> {
57    fn write(&mut self, bytes: &[u8]) -> Result<(), E> {
58        self.writer.write(bytes)
59    }
60}
61
62unsafe impl<W, A: Allocator<E>, S, E> Allocator<E> for Serializer<W, A, S> {
63    unsafe fn push_alloc(
64        &mut self,
65        layout: Layout,
66    ) -> Result<NonNull<[u8]>, E> {
67        // SAFETY: The safety requirements for `A::push_alloc()` are the same as
68        // the safety requirements for `push_alloc()`.
69        unsafe { self.allocator.push_alloc(layout) }
70    }
71
72    unsafe fn pop_alloc(
73        &mut self,
74        ptr: NonNull<u8>,
75        layout: Layout,
76    ) -> Result<(), E> {
77        // SAFETY: The safety requirements for `A::pop_alloc()` are the same as
78        // the safety requirements for `pop_alloc()`.
79        unsafe { self.allocator.pop_alloc(ptr, layout) }
80    }
81}
82
83impl<W, A, S: Sharing<E>, E> Sharing<E> for Serializer<W, A, S> {
84    fn start_sharing(&mut self, address: usize) -> sharing::SharingState {
85        self.sharing.start_sharing(address)
86    }
87
88    fn finish_sharing(&mut self, address: usize, pos: usize) -> Result<(), E> {
89        self.sharing.finish_sharing(address, pos)
90    }
91}