wincode/serde.rs
1#[cfg(feature = "alloc")]
2use alloc::vec::Vec;
3use {
4 crate::{
5 error::{ReadResult, WriteResult},
6 io::{Reader, Writer},
7 schema::{SchemaRead, SchemaWrite},
8 SchemaReadOwned,
9 },
10 core::mem::MaybeUninit,
11};
12
13/// Helper over [`SchemaRead`] that automatically constructs a reader
14/// and initializes a destination.
15///
16/// # Examples
17///
18/// Using containers (indirect deserialization):
19/// ```
20/// # #[cfg(feature = "alloc")] {
21/// # use wincode::{Deserialize, containers};
22/// let vec: Vec<u8> = vec![1, 2, 3];
23/// let bytes = wincode::serialize(&vec).unwrap();
24/// type Dst = containers::Vec<u8>;
25/// let deserialized = Dst::deserialize(&bytes).unwrap();
26/// assert_eq!(vec, deserialized);
27/// # }
28/// ```
29///
30/// Using direct deserialization (`T::Dst = T`):
31/// ```
32/// # #[cfg(feature = "alloc")] {
33/// let vec: Vec<u8> = vec![1, 2, 3];
34/// let bytes = wincode::serialize(&vec).unwrap();
35/// let deserialized: Vec<u8> = wincode::deserialize(&bytes).unwrap();
36/// assert_eq!(vec, deserialized);
37/// # }
38/// ```
39pub trait Deserialize<'de>: SchemaRead<'de> {
40 /// Deserialize `bytes` into a new `Self::Dst`.
41 #[inline(always)]
42 fn deserialize(mut src: &'de [u8]) -> ReadResult<Self::Dst> {
43 <Self as SchemaRead<'de>>::get(&mut src)
44 }
45
46 /// Deserialize `bytes` into `target`.
47 #[inline]
48 fn deserialize_into(mut src: &'de [u8], dst: &mut MaybeUninit<Self::Dst>) -> ReadResult<()> {
49 <Self as SchemaRead<'de>>::read(&mut src, dst)
50 }
51}
52
53impl<'de, T> Deserialize<'de> for T where T: SchemaRead<'de> {}
54
55/// A variant of [`Deserialize`] for types that can be deserialized without borrowing from the reader.
56pub trait DeserializeOwned: SchemaReadOwned {
57 /// Deserialize from the given [`Reader`] into a new `Self::Dst`.
58 #[inline(always)]
59 fn deserialize_from<'de>(
60 src: &mut impl Reader<'de>,
61 ) -> ReadResult<<Self as SchemaRead<'de>>::Dst> {
62 <Self as SchemaRead<'de>>::get(src)
63 }
64
65 /// Deserialize from the given [`Reader`] into `dst`.
66 #[inline]
67 fn deserialize_from_into<'de>(
68 src: &mut impl Reader<'de>,
69 dst: &mut MaybeUninit<<Self as SchemaRead<'de>>::Dst>,
70 ) -> ReadResult<()> {
71 <Self as SchemaRead<'de>>::read(src, dst)
72 }
73}
74
75impl<T> DeserializeOwned for T where T: SchemaReadOwned {}
76
77/// Helper over [`SchemaWrite`] that automatically constructs a writer
78/// and serializes a source.
79///
80/// # Examples
81///
82/// Using containers (indirect serialization):
83/// ```
84/// # #[cfg(feature = "alloc")] {
85/// # use wincode::{Serialize, containers};
86/// let vec: Vec<u8> = vec![1, 2, 3];
87/// type Src = containers::Vec<u8>;
88/// let bytes = Src::serialize(&vec).unwrap();
89/// let deserialized: Vec<u8> = wincode::deserialize(&bytes).unwrap();
90/// assert_eq!(vec, deserialized);
91/// # }
92/// ```
93///
94/// Using direct serialization (`T::Src = T`):
95/// ```
96/// # #[cfg(feature = "alloc")] {
97/// let vec: Vec<u8> = vec![1, 2, 3];
98/// let bytes = wincode::serialize(&vec).unwrap();
99/// let deserialized: Vec<u8> = wincode::deserialize(&bytes).unwrap();
100/// assert_eq!(vec, deserialized);
101/// # }
102/// ```
103pub trait Serialize: SchemaWrite {
104 /// Serialize a serializable type into a `Vec` of bytes.
105 #[cfg(feature = "alloc")]
106 fn serialize(src: &Self::Src) -> WriteResult<Vec<u8>> {
107 let capacity = Self::size_of(src)?;
108 let mut buffer = Vec::with_capacity(capacity);
109 let mut writer = buffer.spare_capacity_mut();
110 Self::serialize_into(&mut writer, src)?;
111 let len = writer.len();
112 unsafe {
113 #[allow(clippy::arithmetic_side_effects)]
114 buffer.set_len(capacity - len);
115 }
116 Ok(buffer)
117 }
118
119 /// Serialize a serializable type into the given byte buffer.
120 #[inline]
121 fn serialize_into(dst: &mut impl Writer, src: &Self::Src) -> WriteResult<()> {
122 <Self as SchemaWrite>::write(dst, src)?;
123 dst.finish()?;
124 Ok(())
125 }
126
127 /// Get the size in bytes of the type when serialized.
128 #[inline]
129 fn serialized_size(src: &Self::Src) -> WriteResult<u64> {
130 Self::size_of(src).map(|size| size as u64)
131 }
132}
133
134impl<T> Serialize for T where T: SchemaWrite + ?Sized {}
135
136/// Deserialize a type from the given bytes.
137///
138/// This is a "simplified" version of [`Deserialize::deserialize`] that
139/// requires the `T::Dst` to be `T`. In other words, a schema type
140/// that deserializes to itself.
141///
142/// This helper exists to match the expected signature of `serde`'s
143/// `Deserialize`, where types that implement `Deserialize` deserialize
144/// into themselves. This will be true of a large number of schema types,
145/// but wont, for example, for specialized container structures.
146///
147/// # Examples
148///
149/// ```
150/// # #[cfg(feature = "alloc")] {
151/// let vec: Vec<u8> = vec![1, 2, 3];
152/// let bytes = wincode::serialize(&vec).unwrap();
153/// let deserialized: Vec<u8> = wincode::deserialize(&bytes).unwrap();
154/// assert_eq!(vec, deserialized);
155/// # }
156/// ```
157#[inline(always)]
158pub fn deserialize<'de, T>(src: &'de [u8]) -> ReadResult<T>
159where
160 T: SchemaRead<'de, Dst = T>,
161{
162 T::deserialize(src)
163}
164
165/// Deserialize a type from the given bytes, with the ability
166/// to form mutable references for types that are [`ZeroCopy`](crate::ZeroCopy).
167/// This can allow mutating the serialized data in place.
168///
169/// # Examples
170///
171/// ## Zero-copy types
172/// ```
173/// # #[cfg(all(feature = "alloc", feature = "derive"))] {
174/// # use wincode::{SchemaWrite, SchemaRead};
175/// # #[derive(Debug, PartialEq, Eq)]
176/// #[derive(SchemaWrite, SchemaRead)]
177/// #[repr(C)]
178/// struct Data {
179/// bytes: [u8; 7],
180/// the_answer: u8,
181/// }
182///
183/// let data = Data { bytes: [0; 7], the_answer: 0 };
184///
185/// let mut serialized = wincode::serialize(&data).unwrap();
186/// let data_mut: &mut Data = wincode::deserialize_mut(&mut serialized).unwrap();
187/// data_mut.bytes = *b"wincode";
188/// data_mut.the_answer = 42;
189///
190/// let deserialized: Data = wincode::deserialize(&serialized).unwrap();
191/// assert_eq!(deserialized, Data { bytes: *b"wincode", the_answer: 42 });
192/// # }
193/// ```
194///
195/// ## Mutable zero-copy members
196/// ```
197/// # #[cfg(all(feature = "alloc", feature = "derive"))] {
198/// # use wincode::{SchemaWrite, SchemaRead};
199/// # #[derive(Debug, PartialEq, Eq)]
200/// #[derive(SchemaWrite, SchemaRead)]
201/// struct Data {
202/// bytes: [u8; 7],
203/// the_answer: u8,
204/// }
205/// # #[derive(Debug, PartialEq, Eq)]
206/// #[derive(SchemaRead)]
207/// struct DataMut<'a> {
208/// bytes: &'a mut [u8; 7],
209/// the_answer: u8,
210/// }
211///
212/// let data = Data { bytes: [0; 7], the_answer: 42 };
213///
214/// let mut serialized = wincode::serialize(&data).unwrap();
215/// let data_mut: DataMut<'_> = wincode::deserialize_mut(&mut serialized).unwrap();
216/// *data_mut.bytes = *b"wincode";
217///
218/// let deserialized: Data = wincode::deserialize(&serialized).unwrap();
219/// assert_eq!(deserialized, Data { bytes: *b"wincode", the_answer: 42 });
220/// # }
221/// ```
222#[inline(always)]
223pub fn deserialize_mut<'de, T>(mut src: &'de mut [u8]) -> ReadResult<T>
224where
225 T: SchemaRead<'de, Dst = T>,
226{
227 <T as SchemaRead<'de>>::get(&mut src)
228}
229
230/// Deserialize a type from the given bytes into the given target.
231///
232/// Like [`deserialize`], but allows the caller to provide their own reader.
233///
234/// Because not all readers will support zero-copy deserialization, this function
235/// requires [`SchemaReadOwned`] instead of [`SchemaRead`]. If you are deserializing
236/// from raw bytes, always prefer [`deserialize`] for maximum flexibility.
237#[inline]
238pub fn deserialize_from<'de, T>(src: &mut impl Reader<'de>) -> ReadResult<T>
239where
240 T: SchemaReadOwned<Dst = T>,
241{
242 T::deserialize_from(src)
243}
244
245/// Serialize a type into a `Vec` of bytes.
246///
247/// This is a "simplified" version of [`Serialize::serialize`] that
248/// requires the `T::Src` to be `T`. In other words, a schema type
249/// that serializes to itself.
250///
251/// This helper exists to match the expected signature of `serde`'s
252/// `Serialize`, where types that implement `Serialize` serialize
253/// themselves. This will be true of a large number of schema types,
254/// but wont, for example, for specialized container structures.
255///
256/// # Examples
257///
258/// ```
259/// let vec: Vec<u8> = vec![1, 2, 3];
260/// let bytes = wincode::serialize(&vec).unwrap();
261/// ```
262#[inline(always)]
263#[cfg(feature = "alloc")]
264pub fn serialize<T>(src: &T) -> WriteResult<Vec<u8>>
265where
266 T: SchemaWrite<Src = T> + ?Sized,
267{
268 T::serialize(src)
269}
270
271/// Serialize a type into the given writer.
272///
273/// Like [`serialize`], but allows the caller to provide their own writer.
274#[inline]
275pub fn serialize_into<T>(dst: &mut impl Writer, src: &T) -> WriteResult<()>
276where
277 T: SchemaWrite<Src = T> + ?Sized,
278{
279 T::serialize_into(dst, src)
280}
281
282/// Get the size in bytes of the type when serialized.
283#[inline(always)]
284pub fn serialized_size<T>(src: &T) -> WriteResult<u64>
285where
286 T: SchemaWrite<Src = T> + ?Sized,
287{
288 T::serialized_size(src)
289}