rkyv/api/low/mod.rs
1//! APIs for environments where allocations cannot be made.
2//!
3//! These APIs require user-provided writers and allocators, and do not support
4//! shared pointers.
5
6#[cfg(feature = "bytecheck")]
7mod checked;
8
9use rancor::Strategy;
10
11#[cfg(feature = "bytecheck")]
12pub use self::checked::*;
13use crate::{
14 access_unchecked,
15 api::{deserialize_using, serialize_using},
16 ser::{Allocator, Serializer, Writer},
17 Archive, Deserialize, Serialize,
18};
19
20/// A general-purpose serializer suitable for environments where allocations
21/// cannot be made.
22///
23/// This is part of the [low-level API](crate::api::low).
24pub type LowSerializer<W, A, E> = Strategy<Serializer<W, A, ()>, E>;
25
26/// A general-purpose deserializer suitable for environments where allocations
27/// cannot be made.
28///
29/// This is part of the [low-level API](crate::api::low).
30pub type LowDeserializer<E> = Strategy<(), E>;
31
32/// Serialize a value using the given allocator and write the bytes to the given
33/// writer.
34///
35/// This is part of the [low-level API](crate::api::low).
36///
37/// # Example
38///
39/// ```
40/// use core::mem::MaybeUninit;
41///
42/// use rkyv::{
43/// access_unchecked,
44/// api::low::to_bytes_in_with_alloc,
45/// rancor::Failure,
46/// ser::{allocator::SubAllocator, writer::Buffer},
47/// util::Align,
48/// with::InlineAsBox,
49/// Archive, Serialize,
50/// };
51///
52/// let mut output = Align([MaybeUninit::<u8>::uninit(); 256]);
53/// let mut alloc = [MaybeUninit::<u8>::uninit(); 256];
54///
55/// #[derive(Archive, Serialize)]
56/// struct Example<'a> {
57/// #[rkyv(with = InlineAsBox)]
58/// inner: &'a i32,
59/// }
60///
61/// let forty_two = 42;
62/// let value = Example { inner: &forty_two };
63///
64/// let bytes = to_bytes_in_with_alloc::<_, _, Failure>(
65/// &value,
66/// Buffer::from(&mut *output),
67/// SubAllocator::new(&mut alloc),
68/// )
69/// .unwrap();
70///
71/// let archived = unsafe { access_unchecked::<ArchivedExample<'_>>(&*bytes) };
72/// assert_eq!(*archived.inner, 42);
73/// ```
74pub fn to_bytes_in_with_alloc<W, A, E>(
75 value: &impl Serialize<LowSerializer<W, A, E>>,
76 writer: W,
77 alloc: A,
78) -> Result<W, E>
79where
80 W: Writer<E>,
81 A: Allocator<E>,
82 E: rancor::Source,
83{
84 let mut serializer = Serializer::new(writer, alloc, ());
85 serialize_using(value, &mut serializer)?;
86 Ok(serializer.into_writer())
87}
88
89/// Deserialize a value from the given bytes.
90///
91/// This function does not check that the data is valid. Use [`from_bytes`] to
92/// validate the data instead.
93///
94/// This is part of the [low-level API](crate::api::low).
95///
96/// # Safety
97///
98/// The byte slice must represent a valid archived type when accessed at the
99/// default root position. See the [module docs](crate::api) for more
100/// information.
101///
102/// # Example
103///
104/// ```
105/// use core::mem::MaybeUninit;
106///
107/// use rkyv::{
108/// access_unchecked,
109/// api::low::{from_bytes_unchecked, to_bytes_in_with_alloc},
110/// rancor::Failure,
111/// ser::{allocator::SubAllocator, writer::Buffer},
112/// util::Align,
113/// with::InlineAsBox,
114/// Archive, Deserialize, Serialize,
115/// };
116///
117/// let mut output = Align([MaybeUninit::<u8>::uninit(); 256]);
118/// let mut alloc = [MaybeUninit::<u8>::uninit(); 256];
119///
120/// #[derive(Archive, Serialize, Deserialize, Debug, PartialEq)]
121/// struct Example {
122/// inner: i32,
123/// }
124///
125/// let value = Example { inner: 42 };
126///
127/// let bytes = to_bytes_in_with_alloc::<_, _, Failure>(
128/// &value,
129/// Buffer::from(&mut *output),
130/// SubAllocator::new(&mut alloc),
131/// )
132/// .unwrap();
133///
134/// let deserialized =
135/// unsafe { from_bytes_unchecked::<Example, Failure>(&*bytes).unwrap() };
136/// assert_eq!(value, deserialized);
137/// ```
138pub unsafe fn from_bytes_unchecked<T, E>(bytes: &[u8]) -> Result<T, E>
139where
140 T: Archive,
141 T::Archived: Deserialize<T, LowDeserializer<E>>,
142{
143 // SAFETY: The caller has guaranteed that a valid `T` is located at the root
144 // position in the byte slice.
145 let archived = unsafe { access_unchecked::<T::Archived>(bytes) };
146 deserialize(archived)
147}
148
149/// Deserialize a value from the given archived value.
150///
151/// This is part of the [low-level API](crate::api::low).
152///
153/// # Example
154///
155/// ```
156/// use core::mem::MaybeUninit;
157///
158/// use rkyv::{
159/// access_unchecked,
160/// api::low::{deserialize, to_bytes_in_with_alloc},
161/// rancor::Failure,
162/// ser::{allocator::SubAllocator, writer::Buffer},
163/// util::Align,
164/// with::InlineAsBox,
165/// Archive, Deserialize, Serialize,
166/// };
167///
168/// let mut output = Align([MaybeUninit::<u8>::uninit(); 256]);
169/// let mut alloc = [MaybeUninit::<u8>::uninit(); 256];
170///
171/// #[derive(Archive, Serialize, Deserialize, Debug, PartialEq)]
172/// struct Example {
173/// inner: i32,
174/// }
175///
176/// let value = Example { inner: 42 };
177///
178/// let bytes = to_bytes_in_with_alloc::<_, _, Failure>(
179/// &value,
180/// Buffer::from(&mut *output),
181/// SubAllocator::new(&mut alloc),
182/// )
183/// .unwrap();
184///
185/// let archived = unsafe { access_unchecked::<ArchivedExample>(&*bytes) };
186/// let deserialized = deserialize::<Example, Failure>(archived).unwrap();
187/// assert_eq!(value, deserialized);
188/// ```
189pub fn deserialize<T, E>(
190 value: &impl Deserialize<T, LowDeserializer<E>>,
191) -> Result<T, E> {
192 deserialize_using(value, &mut ())
193}