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}