Skip to main content

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}