Skip to main content

wincode/
serde.rs

1#[cfg(feature = "alloc")]
2use alloc::vec::Vec;
3use {
4    crate::{
5        config::{self, DefaultConfig},
6        error::{ReadResult, WriteResult},
7        io::{Reader, Writer},
8        schema::{SchemaRead, SchemaWrite},
9        SchemaReadOwned,
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, with the ability
161/// to form mutable references for types that are [`ZeroCopy`](crate::ZeroCopy).
162/// This can allow mutating the serialized data in place.
163///
164/// # Examples
165///
166/// ## Zero-copy types
167/// ```
168/// # #[cfg(all(feature = "alloc", feature = "derive"))] {
169/// # use wincode::{SchemaWrite, SchemaRead};
170/// # #[derive(Debug, PartialEq, Eq)]
171/// #[derive(SchemaWrite, SchemaRead)]
172/// #[repr(C)]
173/// struct Data {
174///     bytes: [u8; 7],
175///     the_answer: u8,
176/// }
177///
178/// let data = Data { bytes: [0; 7], the_answer: 0 };
179///
180/// let mut serialized = wincode::serialize(&data).unwrap();
181/// let data_mut: &mut Data = wincode::deserialize_mut(&mut serialized).unwrap();
182/// data_mut.bytes = *b"wincode";
183/// data_mut.the_answer = 42;
184///
185/// let deserialized: Data = wincode::deserialize(&serialized).unwrap();
186/// assert_eq!(deserialized, Data { bytes: *b"wincode", the_answer: 42 });
187/// # }
188/// ```
189///
190/// ## Mutable zero-copy members
191/// ```
192/// # #[cfg(all(feature = "alloc", feature = "derive"))] {
193/// # use wincode::{SchemaWrite, SchemaRead};
194/// # #[derive(Debug, PartialEq, Eq)]
195/// #[derive(SchemaWrite, SchemaRead)]
196/// struct Data {
197///     bytes: [u8; 7],
198///     the_answer: u8,
199/// }
200/// # #[derive(Debug, PartialEq, Eq)]
201/// #[derive(SchemaRead)]
202/// struct DataMut<'a> {
203///     bytes: &'a mut [u8; 7],
204///     the_answer: u8,
205/// }
206///
207/// let data = Data { bytes: [0; 7], the_answer: 42 };
208///
209/// let mut serialized = wincode::serialize(&data).unwrap();
210/// let data_mut: DataMut<'_> = wincode::deserialize_mut(&mut serialized).unwrap();
211/// *data_mut.bytes = *b"wincode";
212///
213/// let deserialized: Data = wincode::deserialize(&serialized).unwrap();
214/// assert_eq!(deserialized, Data { bytes: *b"wincode", the_answer: 42 });
215/// # }
216/// ```
217#[inline(always)]
218pub fn deserialize_mut<'de, T>(src: &'de mut [u8]) -> ReadResult<T>
219where
220    T: SchemaRead<'de, DefaultConfig, Dst = T>,
221{
222    <T as SchemaRead<'de, DefaultConfig>>::get(src)
223}
224
225/// Deserialize a type from the given bytes into the given target.
226///
227/// Like [`deserialize`], but allows the caller to provide their own reader.
228///
229/// Because not all readers will support zero-copy deserialization, this function
230/// requires [`SchemaReadOwned`] instead of [`SchemaRead`]. If you are deserializing
231/// from raw bytes, always prefer [`deserialize`] for maximum flexibility.
232#[inline(always)]
233pub fn deserialize_from<'de, T>(src: impl Reader<'de>) -> ReadResult<T>
234where
235    T: SchemaReadOwned<DefaultConfig, Dst = T>,
236{
237    T::deserialize_from(src)
238}
239
240/// Serialize a type into a `Vec` of bytes.
241///
242/// This is a "simplified" version of [`Serialize::serialize`] that
243/// requires the `T::Src` to be `T`. In other words, a schema type
244/// that serializes to itself.
245///
246/// This helper exists to match the expected signature of `serde`'s
247/// `Serialize`, where types that implement `Serialize` serialize
248/// themselves. This will be true of a large number of schema types,
249/// but wont, for example, for specialized container structures.
250///
251/// # Examples
252///
253/// ```
254/// let vec: Vec<u8> = vec![1, 2, 3];
255/// let bytes = wincode::serialize(&vec).unwrap();
256/// ```
257#[inline(always)]
258#[cfg(feature = "alloc")]
259pub fn serialize<T>(src: &T) -> WriteResult<Vec<u8>>
260where
261    T: SchemaWrite<DefaultConfig, Src = T> + ?Sized,
262{
263    T::serialize(src)
264}
265
266/// Serialize a type into the given writer.
267///
268/// Like [`serialize`], but allows the caller to provide their own writer.
269#[inline]
270pub fn serialize_into<T>(dst: impl Writer, src: &T) -> WriteResult<()>
271where
272    T: SchemaWrite<DefaultConfig, Src = T> + ?Sized,
273{
274    T::serialize_into(dst, src)
275}
276
277/// Get the size in bytes of the type when serialized.
278#[inline(always)]
279pub fn serialized_size<T>(src: &T) -> WriteResult<u64>
280where
281    T: SchemaWrite<DefaultConfig, Src = T> + ?Sized,
282{
283    T::serialized_size(src)
284}