Skip to main content

wincode/
serde.rs

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