/rust/registry/src/index.crates.io-1949cf8c6b5b557f/postcard-1.1.3/src/ser/mod.rs
Line | Count | Source |
1 | | use crate::error::{Error, Result}; |
2 | | use crate::ser::flavors::{Cobs, Flavor, Slice}; |
3 | | use serde::Serialize; |
4 | | |
5 | | #[cfg(feature = "heapless")] |
6 | | use crate::ser::flavors::HVec; |
7 | | |
8 | | #[cfg(feature = "heapless")] |
9 | | use heapless::Vec; |
10 | | |
11 | | #[cfg(feature = "alloc")] |
12 | | use crate::ser::flavors::AllocVec; |
13 | | |
14 | | #[cfg(feature = "alloc")] |
15 | | extern crate alloc; |
16 | | |
17 | | use crate::ser::serializer::Serializer; |
18 | | |
19 | | pub mod flavors; |
20 | | pub(crate) mod serializer; |
21 | | |
22 | | /// Serialize a `T` to the given slice, with the resulting slice containing |
23 | | /// data in a serialized then COBS encoded format. The terminating sentinel |
24 | | /// `0x00` byte is included in the output buffer. |
25 | | /// |
26 | | /// When successful, this function returns the slice containing the |
27 | | /// serialized and encoded message. |
28 | | /// |
29 | | /// ## Example |
30 | | /// |
31 | | /// ```rust |
32 | | /// use postcard::to_slice_cobs; |
33 | | /// let mut buf = [0u8; 32]; |
34 | | /// |
35 | | /// let used = to_slice_cobs(&false, &mut buf).unwrap(); |
36 | | /// assert_eq!(used, &[0x01, 0x01, 0x00]); |
37 | | /// |
38 | | /// let used = to_slice_cobs("1", &mut buf).unwrap(); |
39 | | /// assert_eq!(used, &[0x03, 0x01, b'1', 0x00]); |
40 | | /// |
41 | | /// let used = to_slice_cobs("Hi!", &mut buf).unwrap(); |
42 | | /// assert_eq!(used, &[0x05, 0x03, b'H', b'i', b'!', 0x00]); |
43 | | /// |
44 | | /// let data: &[u8] = &[0x01u8, 0x00, 0x20, 0x30]; |
45 | | /// let used = to_slice_cobs(data, &mut buf).unwrap(); |
46 | | /// assert_eq!(used, &[0x03, 0x04, 0x01, 0x03, 0x20, 0x30, 0x00]); |
47 | | /// ``` |
48 | 0 | pub fn to_slice_cobs<'a, 'b, T>(value: &'b T, buf: &'a mut [u8]) -> Result<&'a mut [u8]> |
49 | 0 | where |
50 | 0 | T: Serialize + ?Sized, |
51 | | { |
52 | 0 | serialize_with_flavor::<T, Cobs<Slice<'a>>, &'a mut [u8]>( |
53 | 0 | value, |
54 | 0 | Cobs::try_new(Slice::new(buf))?, |
55 | | ) |
56 | 0 | } |
57 | | |
58 | | /// Serialize a `T` to the given slice, with the resulting slice containing |
59 | | /// data in a serialized format. |
60 | | /// |
61 | | /// When successful, this function returns the slice containing the |
62 | | /// serialized message |
63 | | /// |
64 | | /// ## Example |
65 | | /// |
66 | | /// ```rust |
67 | | /// use postcard::to_slice; |
68 | | /// let mut buf = [0u8; 32]; |
69 | | /// |
70 | | /// let used = to_slice(&true, &mut buf).unwrap(); |
71 | | /// assert_eq!(used, &[0x01]); |
72 | | /// |
73 | | /// let used = to_slice("Hi!", &mut buf).unwrap(); |
74 | | /// assert_eq!(used, &[0x03, b'H', b'i', b'!']); |
75 | | /// |
76 | | /// // NOTE: postcard handles `&[u8]` and `&[u8; N]` differently. |
77 | | /// let data: &[u8] = &[0x01u8, 0x00, 0x20, 0x30]; |
78 | | /// let used = to_slice(data, &mut buf).unwrap(); |
79 | | /// assert_eq!(used, &[0x04, 0x01, 0x00, 0x20, 0x30]); |
80 | | /// |
81 | | /// let data: &[u8; 4] = &[0x01u8, 0x00, 0x20, 0x30]; |
82 | | /// let used = to_slice(data, &mut buf).unwrap(); |
83 | | /// assert_eq!(used, &[0x01, 0x00, 0x20, 0x30]); |
84 | | /// ``` |
85 | 0 | pub fn to_slice<'a, 'b, T>(value: &'b T, buf: &'a mut [u8]) -> Result<&'a mut [u8]> |
86 | 0 | where |
87 | 0 | T: Serialize + ?Sized, |
88 | | { |
89 | 0 | serialize_with_flavor::<T, Slice<'a>, &'a mut [u8]>(value, Slice::new(buf)) |
90 | 0 | } |
91 | | |
92 | | /// Serialize a `T` to a `heapless::Vec<u8>`, with the `Vec` containing |
93 | | /// data in a serialized then COBS encoded format. The terminating sentinel |
94 | | /// `0x00` byte is included in the output `Vec`. |
95 | | /// |
96 | | /// ## Example |
97 | | /// |
98 | | /// ```rust |
99 | | /// use postcard::to_vec_cobs; |
100 | | /// use heapless::Vec; |
101 | | /// use core::ops::Deref; |
102 | | /// |
103 | | /// let ser: Vec<u8, 32> = to_vec_cobs(&false).unwrap(); |
104 | | /// assert_eq!(ser.deref(), &[0x01, 0x01, 0x00]); |
105 | | /// |
106 | | /// let ser: Vec<u8, 32> = to_vec_cobs("Hi!").unwrap(); |
107 | | /// assert_eq!(ser.deref(), &[0x05, 0x03, b'H', b'i', b'!', 0x00]); |
108 | | /// |
109 | | /// // NOTE: postcard handles `&[u8]` and `&[u8; N]` differently. |
110 | | /// let data: &[u8] = &[0x01u8, 0x00, 0x20, 0x30]; |
111 | | /// let ser: Vec<u8, 32> = to_vec_cobs(data).unwrap(); |
112 | | /// assert_eq!(ser.deref(), &[0x03, 0x04, 0x01, 0x03, 0x20, 0x30, 0x00]); |
113 | | /// |
114 | | /// let data: &[u8; 4] = &[0x01u8, 0x00, 0x20, 0x30]; |
115 | | /// let ser: Vec<u8, 32> = to_vec_cobs(data).unwrap(); |
116 | | /// assert_eq!(ser.deref(), &[0x02, 0x01, 0x03, 0x20, 0x30, 0x00]); |
117 | | /// ``` |
118 | | #[cfg(feature = "heapless")] |
119 | | #[cfg_attr(docsrs, doc(cfg(feature = "heapless")))] |
120 | | pub fn to_vec_cobs<T, const B: usize>(value: &T) -> Result<Vec<u8, B>> |
121 | | where |
122 | | T: Serialize + ?Sized, |
123 | | { |
124 | | serialize_with_flavor::<T, Cobs<HVec<B>>, Vec<u8, B>>(value, Cobs::try_new(HVec::default())?) |
125 | | } |
126 | | |
127 | | /// Serialize a `T` to a `heapless::Vec<u8>`, with the `Vec` containing |
128 | | /// data in a serialized format. |
129 | | /// |
130 | | /// ## Example |
131 | | /// |
132 | | /// ```rust |
133 | | /// use postcard::to_vec; |
134 | | /// use heapless::Vec; |
135 | | /// use core::ops::Deref; |
136 | | /// |
137 | | /// let ser: Vec<u8, 32> = to_vec(&true).unwrap(); |
138 | | /// assert_eq!(ser.deref(), &[0x01]); |
139 | | /// |
140 | | /// let ser: Vec<u8, 32> = to_vec("Hi!").unwrap(); |
141 | | /// assert_eq!(ser.deref(), &[0x03, b'H', b'i', b'!']); |
142 | | /// |
143 | | /// // NOTE: postcard handles `&[u8]` and `&[u8; N]` differently. |
144 | | /// let data: &[u8] = &[0x01u8, 0x00, 0x20, 0x30]; |
145 | | /// let ser: Vec<u8, 32> = to_vec(data).unwrap(); |
146 | | /// assert_eq!(ser.deref(), &[0x04, 0x01, 0x00, 0x20, 0x30]); |
147 | | /// |
148 | | /// let data: &[u8; 4] = &[0x01u8, 0x00, 0x20, 0x30]; |
149 | | /// let ser: Vec<u8, 32> = to_vec(data).unwrap(); |
150 | | /// assert_eq!(ser.deref(), &[0x01, 0x00, 0x20, 0x30]); |
151 | | /// ``` |
152 | | #[cfg(feature = "heapless")] |
153 | | #[cfg_attr(docsrs, doc(cfg(feature = "heapless")))] |
154 | | pub fn to_vec<T, const B: usize>(value: &T) -> Result<Vec<u8, B>> |
155 | | where |
156 | | T: Serialize + ?Sized, |
157 | | { |
158 | | serialize_with_flavor::<T, HVec<B>, Vec<u8, B>>(value, HVec::default()) |
159 | | } |
160 | | |
161 | | /// Serialize a `T` to a `std::vec::Vec<u8>`. |
162 | | /// |
163 | | /// ## Example |
164 | | /// |
165 | | /// ```rust |
166 | | /// use postcard::to_stdvec; |
167 | | /// |
168 | | /// let ser: Vec<u8> = to_stdvec(&true).unwrap(); |
169 | | /// assert_eq!(ser.as_slice(), &[0x01]); |
170 | | /// |
171 | | /// let ser: Vec<u8> = to_stdvec("Hi!").unwrap(); |
172 | | /// assert_eq!(ser.as_slice(), &[0x03, b'H', b'i', b'!']); |
173 | | /// ``` |
174 | | #[cfg(feature = "use-std")] |
175 | | #[cfg_attr(docsrs, doc(cfg(feature = "use-std")))] |
176 | | #[inline] |
177 | | pub fn to_stdvec<T>(value: &T) -> Result<std::vec::Vec<u8>> |
178 | | where |
179 | | T: Serialize + ?Sized, |
180 | | { |
181 | | to_allocvec(value) |
182 | | } |
183 | | |
184 | | /// Serialize and COBS encode a `T` to a `std::vec::Vec<u8>`. |
185 | | /// |
186 | | /// The terminating sentinel `0x00` byte is included in the output. |
187 | | /// |
188 | | /// ## Example |
189 | | /// |
190 | | /// ```rust |
191 | | /// use postcard::to_stdvec_cobs; |
192 | | /// |
193 | | /// let ser: Vec<u8> = to_stdvec_cobs(&true).unwrap(); |
194 | | /// assert_eq!(ser.as_slice(), &[0x02, 0x01, 0x00]); |
195 | | /// |
196 | | /// let ser: Vec<u8> = to_stdvec_cobs("Hi!").unwrap(); |
197 | | /// assert_eq!(ser.as_slice(), &[0x05, 0x03, b'H', b'i', b'!', 0x00]); |
198 | | /// ``` |
199 | | #[cfg(feature = "use-std")] |
200 | | #[cfg_attr(docsrs, doc(cfg(feature = "use-std")))] |
201 | | #[inline] |
202 | | pub fn to_stdvec_cobs<T>(value: &T) -> Result<std::vec::Vec<u8>> |
203 | | where |
204 | | T: Serialize + ?Sized, |
205 | | { |
206 | | to_allocvec_cobs(value) |
207 | | } |
208 | | |
209 | | /// Serialize a `T` to an `alloc::vec::Vec<u8>`. |
210 | | /// |
211 | | /// ## Example |
212 | | /// |
213 | | /// ```rust |
214 | | /// use postcard::to_allocvec; |
215 | | /// |
216 | | /// let ser: Vec<u8> = to_allocvec(&true).unwrap(); |
217 | | /// assert_eq!(ser.as_slice(), &[0x01]); |
218 | | /// |
219 | | /// let ser: Vec<u8> = to_allocvec("Hi!").unwrap(); |
220 | | /// assert_eq!(ser.as_slice(), &[0x03, b'H', b'i', b'!']); |
221 | | /// ``` |
222 | | #[cfg(feature = "alloc")] |
223 | | #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] |
224 | 0 | pub fn to_allocvec<T>(value: &T) -> Result<alloc::vec::Vec<u8>> |
225 | 0 | where |
226 | 0 | T: Serialize + ?Sized, |
227 | | { |
228 | 0 | serialize_with_flavor::<T, AllocVec, alloc::vec::Vec<u8>>(value, AllocVec::new()) |
229 | 0 | } Unexecuted instantiation: postcard::ser::to_allocvec::<fallow_graph::cache::store::GraphCacheStore> Unexecuted instantiation: postcard::ser::to_allocvec::<_> |
230 | | |
231 | | /// Serialize and COBS encode a `T` to an `alloc::vec::Vec<u8>`. |
232 | | /// |
233 | | /// The terminating sentinel `0x00` byte is included in the output. |
234 | | /// |
235 | | /// ## Example |
236 | | /// |
237 | | /// ```rust |
238 | | /// use postcard::to_allocvec_cobs; |
239 | | /// |
240 | | /// let ser: Vec<u8> = to_allocvec_cobs(&true).unwrap(); |
241 | | /// assert_eq!(ser.as_slice(), &[0x02, 0x01, 0x00]); |
242 | | /// |
243 | | /// let ser: Vec<u8> = to_allocvec_cobs("Hi!").unwrap(); |
244 | | /// assert_eq!(ser.as_slice(), &[0x05, 0x03, b'H', b'i', b'!', 0x00]); |
245 | | /// ``` |
246 | | #[cfg(feature = "alloc")] |
247 | | #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] |
248 | 0 | pub fn to_allocvec_cobs<T>(value: &T) -> Result<alloc::vec::Vec<u8>> |
249 | 0 | where |
250 | 0 | T: Serialize + ?Sized, |
251 | | { |
252 | 0 | serialize_with_flavor::<T, Cobs<AllocVec>, alloc::vec::Vec<u8>>( |
253 | 0 | value, |
254 | 0 | Cobs::try_new(AllocVec::new())?, |
255 | | ) |
256 | 0 | } |
257 | | |
258 | | /// Serialize a `T` to a [`core::iter::Extend`], |
259 | | /// ## Example |
260 | | /// |
261 | | /// ```rust |
262 | | /// use postcard::to_extend; |
263 | | /// let mut vec = Vec::new(); |
264 | | /// |
265 | | /// let ser = to_extend(&true, vec).unwrap(); |
266 | | /// let vec = to_extend("Hi!", ser).unwrap(); |
267 | | /// assert_eq!(&vec[0..5], &[0x01, 0x03, b'H', b'i', b'!']); |
268 | | /// ``` |
269 | 0 | pub fn to_extend<T, W>(value: &T, writer: W) -> Result<W> |
270 | 0 | where |
271 | 0 | T: Serialize + ?Sized, |
272 | 0 | W: core::iter::Extend<u8>, |
273 | | { |
274 | 0 | serialize_with_flavor::<T, _, _>(value, flavors::ExtendFlavor::new(writer)) |
275 | 0 | } |
276 | | |
277 | | /// Serialize a `T` to an [`embedded_io Write`](crate::eio::Write), |
278 | | /// ## Example |
279 | | /// |
280 | | /// ```rust |
281 | | /// use postcard::to_eio; |
282 | | /// let mut buf: [u8; 32] = [0; 32]; |
283 | | /// let mut writer: &mut [u8] = &mut buf; |
284 | | /// |
285 | | /// let ser = to_eio(&true, &mut writer).unwrap(); |
286 | | /// to_eio("Hi!", ser).unwrap(); |
287 | | /// assert_eq!(&buf[0..5], &[0x01, 0x03, b'H', b'i', b'!']); |
288 | | /// ``` |
289 | | #[cfg(any(feature = "embedded-io-04", feature = "embedded-io-06"))] |
290 | | pub fn to_eio<T, W>(value: &T, writer: W) -> Result<W> |
291 | | where |
292 | | T: Serialize + ?Sized, |
293 | | W: crate::eio::Write, |
294 | | { |
295 | | serialize_with_flavor::<T, _, _>(value, flavors::eio::WriteFlavor::new(writer)) |
296 | | } |
297 | | |
298 | | /// Serialize a `T` to a [`std::io::Write`], |
299 | | /// ## Example |
300 | | /// |
301 | | /// ```rust |
302 | | /// use postcard::to_io; |
303 | | /// let mut buf: [u8; 32] = [0; 32]; |
304 | | /// let mut writer: &mut [u8] = &mut buf; |
305 | | /// |
306 | | /// let ser = to_io(&true, &mut writer).unwrap(); |
307 | | /// to_io("Hi!", ser).unwrap(); |
308 | | /// assert_eq!(&buf[0..5], &[0x01, 0x03, b'H', b'i', b'!']); |
309 | | /// ``` |
310 | | #[cfg(feature = "use-std")] |
311 | | pub fn to_io<T, W>(value: &T, writer: W) -> Result<W> |
312 | | where |
313 | | T: Serialize + ?Sized, |
314 | | W: std::io::Write, |
315 | | { |
316 | | serialize_with_flavor::<T, _, _>(value, flavors::io::WriteFlavor::new(writer)) |
317 | | } |
318 | | |
319 | | /// Conveniently serialize a `T` to the given slice, with the resulting slice containing |
320 | | /// data followed by a 32-bit CRC. The CRC bytes are included in the output buffer. |
321 | | /// |
322 | | /// When successful, this function returns the slice containing the |
323 | | /// serialized and encoded message. |
324 | | /// |
325 | | /// ## Example |
326 | | /// |
327 | | /// ```rust |
328 | | /// use crc::{Crc, CRC_32_ISCSI}; |
329 | | /// |
330 | | /// let mut buf = [0; 9]; |
331 | | /// |
332 | | /// let data: &[u8] = &[0x01, 0x00, 0x20, 0x30]; |
333 | | /// let crc = Crc::<u32>::new(&CRC_32_ISCSI); |
334 | | /// let used = postcard::to_slice_crc32(data, &mut buf, crc.digest()).unwrap(); |
335 | | /// assert_eq!(used, &[0x04, 0x01, 0x00, 0x20, 0x30, 0x8E, 0xC8, 0x1A, 0x37]); |
336 | | /// ``` |
337 | | /// |
338 | | /// See the `ser_flavors::crc` module for the complete set of functions. |
339 | | #[cfg(feature = "use-crc")] |
340 | | #[cfg_attr(docsrs, doc(cfg(feature = "use-crc")))] |
341 | | #[inline] |
342 | | pub fn to_slice_crc32<'a, T>( |
343 | | value: &T, |
344 | | buf: &'a mut [u8], |
345 | | digest: crc::Digest<'_, u32>, |
346 | | ) -> Result<&'a mut [u8]> |
347 | | where |
348 | | T: Serialize + ?Sized, |
349 | | { |
350 | | flavors::crc::to_slice_u32(value, buf, digest) |
351 | | } |
352 | | |
353 | | /// Conveniently serialize a `T` to a `heapless::Vec<u8>`, with the `Vec` containing |
354 | | /// data followed by a 32-bit CRC. The CRC bytes are included in the output `Vec`. |
355 | | /// |
356 | | /// ## Example |
357 | | /// |
358 | | /// ```rust |
359 | | /// use crc::{Crc, CRC_32_ISCSI}; |
360 | | /// use heapless::Vec; |
361 | | /// use core::ops::Deref; |
362 | | /// |
363 | | /// // NOTE: postcard handles `&[u8]` and `&[u8; N]` differently. |
364 | | /// let data: &[u8] = &[0x01u8, 0x00, 0x20, 0x30]; |
365 | | /// let crc = Crc::<u32>::new(&CRC_32_ISCSI); |
366 | | /// let ser: Vec<u8, 32> = postcard::to_vec_crc32(data, crc.digest()).unwrap(); |
367 | | /// assert_eq!(ser.deref(), &[0x04, 0x01, 0x00, 0x20, 0x30, 0x8E, 0xC8, 0x1A, 0x37]); |
368 | | /// |
369 | | /// let data: &[u8; 4] = &[0x01u8, 0x00, 0x20, 0x30]; |
370 | | /// let ser: Vec<u8, 32> = postcard::to_vec_crc32(data, crc.digest()).unwrap(); |
371 | | /// assert_eq!(ser.deref(), &[0x01, 0x00, 0x20, 0x30, 0xCC, 0x4B, 0x4A, 0xDA]); |
372 | | /// ``` |
373 | | /// |
374 | | /// See the `ser_flavors::crc` module for the complete set of functions. |
375 | | #[cfg(all(feature = "use-crc", feature = "heapless"))] |
376 | | #[cfg_attr(docsrs, doc(cfg(all(feature = "use-crc", feature = "heapless"))))] |
377 | | #[inline] |
378 | | pub fn to_vec_crc32<T, const B: usize>( |
379 | | value: &T, |
380 | | digest: crc::Digest<'_, u32>, |
381 | | ) -> Result<heapless::Vec<u8, B>> |
382 | | where |
383 | | T: Serialize + ?Sized, |
384 | | { |
385 | | flavors::crc::to_vec_u32(value, digest) |
386 | | } |
387 | | |
388 | | /// Conveniently serialize a `T` to a `heapless::Vec<u8>`, with the `Vec` containing |
389 | | /// data followed by a 32-bit CRC. The CRC bytes are included in the output `Vec`. |
390 | | /// |
391 | | /// ## Example |
392 | | /// |
393 | | /// ```rust |
394 | | /// use crc::{Crc, CRC_32_ISCSI}; |
395 | | /// use core::ops::Deref; |
396 | | /// |
397 | | /// // NOTE: postcard handles `&[u8]` and `&[u8; N]` differently. |
398 | | /// let data: &[u8] = &[0x01u8, 0x00, 0x20, 0x30]; |
399 | | /// let crc = Crc::<u32>::new(&CRC_32_ISCSI); |
400 | | /// let ser: Vec<u8> = postcard::to_stdvec_crc32(data, crc.digest()).unwrap(); |
401 | | /// assert_eq!(ser.deref(), &[0x04, 0x01, 0x00, 0x20, 0x30, 0x8E, 0xC8, 0x1A, 0x37]); |
402 | | /// |
403 | | /// let data: &[u8; 4] = &[0x01u8, 0x00, 0x20, 0x30]; |
404 | | /// let ser: Vec<u8> = postcard::to_stdvec_crc32(data, crc.digest()).unwrap(); |
405 | | /// assert_eq!(ser.deref(), &[0x01, 0x00, 0x20, 0x30, 0xCC, 0x4B, 0x4A, 0xDA]); |
406 | | /// ``` |
407 | | /// |
408 | | /// See the `ser_flavors::crc` module for the complete set of functions. |
409 | | #[cfg(all(feature = "use-crc", feature = "use-std"))] |
410 | | #[cfg_attr(docsrs, doc(cfg(all(feature = "use-crc", feature = "use-std"))))] |
411 | | #[inline] |
412 | | pub fn to_stdvec_crc32<T>(value: &T, digest: crc::Digest<'_, u32>) -> Result<std::vec::Vec<u8>> |
413 | | where |
414 | | T: Serialize + ?Sized, |
415 | | { |
416 | | flavors::crc::to_allocvec_u32(value, digest) |
417 | | } |
418 | | |
419 | | /// Conveniently serialize a `T` to a `heapless::Vec<u8>`, with the `Vec` containing |
420 | | /// data followed by a 32-bit CRC. The CRC bytes are included in the output `Vec`. |
421 | | /// |
422 | | /// ## Example |
423 | | /// |
424 | | /// ```rust |
425 | | /// use crc::{Crc, CRC_32_ISCSI}; |
426 | | /// use core::ops::Deref; |
427 | | /// |
428 | | /// // NOTE: postcard handles `&[u8]` and `&[u8; N]` differently. |
429 | | /// let data: &[u8] = &[0x01u8, 0x00, 0x20, 0x30]; |
430 | | /// let crc = Crc::<u32>::new(&CRC_32_ISCSI); |
431 | | /// let ser: Vec<u8> = postcard::to_allocvec_crc32(data, crc.digest()).unwrap(); |
432 | | /// assert_eq!(ser.deref(), &[0x04, 0x01, 0x00, 0x20, 0x30, 0x8E, 0xC8, 0x1A, 0x37]); |
433 | | /// |
434 | | /// let data: &[u8; 4] = &[0x01u8, 0x00, 0x20, 0x30]; |
435 | | /// let ser: Vec<u8> = postcard::to_allocvec_crc32(data, crc.digest()).unwrap(); |
436 | | /// assert_eq!(ser.deref(), &[0x01, 0x00, 0x20, 0x30, 0xCC, 0x4B, 0x4A, 0xDA]); |
437 | | /// ``` |
438 | | /// |
439 | | /// See the `ser_flavors::crc` module for the complete set of functions. |
440 | | #[cfg(all(feature = "use-crc", feature = "alloc"))] |
441 | | #[cfg_attr(docsrs, doc(cfg(all(feature = "use-crc", feature = "alloc"))))] |
442 | | #[inline] |
443 | | pub fn to_allocvec_crc32<T>(value: &T, digest: crc::Digest<'_, u32>) -> Result<alloc::vec::Vec<u8>> |
444 | | where |
445 | | T: Serialize + ?Sized, |
446 | | { |
447 | | flavors::crc::to_allocvec_u32(value, digest) |
448 | | } |
449 | | |
450 | | /// `serialize_with_flavor()` has three generic parameters, `T, F, O`. |
451 | | /// |
452 | | /// * `T`: This is the type that is being serialized |
453 | | /// * `S`: This is the Storage that is used during serialization |
454 | | /// * `O`: This is the resulting storage type that is returned containing the serialized data |
455 | | /// |
456 | | /// For more information about how Flavors work, please see the |
457 | | /// [`flavors` module documentation](./flavors/index.html). |
458 | | /// |
459 | | /// ```rust |
460 | | /// use postcard::{ |
461 | | /// serialize_with_flavor, |
462 | | /// ser_flavors::{Cobs, Slice}, |
463 | | /// }; |
464 | | /// |
465 | | /// let mut buf = [0u8; 32]; |
466 | | /// |
467 | | /// let data: &[u8] = &[0x01, 0x00, 0x20, 0x30]; |
468 | | /// let buffer = &mut [0u8; 32]; |
469 | | /// let res = serialize_with_flavor::<[u8], Cobs<Slice>, &mut [u8]>( |
470 | | /// data, |
471 | | /// Cobs::try_new(Slice::new(buffer)).unwrap(), |
472 | | /// ).unwrap(); |
473 | | /// |
474 | | /// assert_eq!(res, &[0x03, 0x04, 0x01, 0x03, 0x20, 0x30, 0x00]); |
475 | | /// ``` |
476 | 0 | pub fn serialize_with_flavor<T, S, O>(value: &T, storage: S) -> Result<O> |
477 | 0 | where |
478 | 0 | T: Serialize + ?Sized, |
479 | 0 | S: Flavor<Output = O>, |
480 | | { |
481 | 0 | let mut serializer = Serializer { output: storage }; |
482 | 0 | value.serialize(&mut serializer)?; |
483 | 0 | serializer |
484 | 0 | .output |
485 | 0 | .finalize() |
486 | 0 | .map_err(|_| Error::SerializeBufferFull) |
487 | 0 | } Unexecuted instantiation: postcard::ser::serialize_with_flavor::<fallow_graph::cache::store::GraphCacheStore, postcard::ser::flavors::alloc_vec::AllocVec, alloc::vec::Vec<u8>> Unexecuted instantiation: postcard::ser::serialize_with_flavor::<_, _, _> |
488 | | |
489 | | /// Compute the size of the postcard serialization of `T`. |
490 | 0 | pub fn serialized_size<T>(value: &T) -> Result<usize> |
491 | 0 | where |
492 | 0 | T: Serialize + ?Sized, |
493 | | { |
494 | 0 | serialize_with_flavor::<T, flavors::Size, usize>(value, flavors::Size::default()) |
495 | 0 | } |
496 | | |
497 | | #[cfg(feature = "heapless")] |
498 | | #[cfg(test)] |
499 | | mod test { |
500 | | use super::*; |
501 | | use crate::max_size::MaxSize; |
502 | | use crate::varint::{varint_max, varint_usize}; |
503 | | use core::fmt::Write; |
504 | | use core::ops::{Deref, DerefMut}; |
505 | | use heapless::{FnvIndexMap, String}; |
506 | | use serde::Deserialize; |
507 | | |
508 | | #[test] |
509 | | fn ser_u8() { |
510 | | let output: Vec<u8, 1> = to_vec(&0x05u8).unwrap(); |
511 | | assert_eq!(&[5], output.deref()); |
512 | | assert!(output.len() == serialized_size(&0x05u8).unwrap()); |
513 | | assert!(output.len() <= Vec::<u8, 1>::POSTCARD_MAX_SIZE); |
514 | | } |
515 | | |
516 | | #[test] |
517 | | fn ser_u16() { |
518 | | const SZ: usize = varint_max::<u16>(); |
519 | | let output: Vec<u8, SZ> = to_vec(&0xA5C7u16).unwrap(); |
520 | | assert_eq!(&[0xC7, 0xCB, 0x02], output.deref()); |
521 | | assert!(output.len() == serialized_size(&0xA5C7u16).unwrap()); |
522 | | assert!(output.len() <= Vec::<u8, SZ>::POSTCARD_MAX_SIZE); |
523 | | } |
524 | | |
525 | | #[test] |
526 | | fn ser_u32() { |
527 | | const SZ: usize = varint_max::<u32>(); |
528 | | let output: Vec<u8, SZ> = to_vec(&0xCDAB3412u32).unwrap(); |
529 | | assert_eq!(&[0x92, 0xE8, 0xAC, 0xED, 0x0C], output.deref()); |
530 | | assert!(output.len() == serialized_size(&0xCDAB3412u32).unwrap()); |
531 | | assert!(output.len() <= Vec::<u8, SZ>::POSTCARD_MAX_SIZE); |
532 | | } |
533 | | |
534 | | #[test] |
535 | | fn ser_u64() { |
536 | | const SZ: usize = varint_max::<u64>(); |
537 | | let output: Vec<u8, SZ> = to_vec(&0x1234_5678_90AB_CDEFu64).unwrap(); |
538 | | assert_eq!( |
539 | | &[0xEF, 0x9B, 0xAF, 0x85, 0x89, 0xCF, 0x95, 0x9A, 0x12], |
540 | | output.deref() |
541 | | ); |
542 | | assert!(output.len() == serialized_size(&0x1234_5678_90AB_CDEFu64).unwrap()); |
543 | | assert!(output.len() <= Vec::<u8, SZ>::POSTCARD_MAX_SIZE); |
544 | | } |
545 | | |
546 | | #[test] |
547 | | fn ser_u128() { |
548 | | const SZ: usize = varint_max::<u128>(); |
549 | | let output: Vec<u8, SZ> = to_vec(&0x1234_5678_90AB_CDEF_1234_5678_90AB_CDEFu128).unwrap(); |
550 | | assert_eq!( |
551 | | &[ |
552 | | 0xEF, 0x9B, 0xAF, 0x85, 0x89, 0xCF, 0x95, 0x9A, 0x92, 0xDE, 0xB7, 0xDE, 0x8A, 0x92, |
553 | | 0x9E, 0xAB, 0xB4, 0x24, |
554 | | ], |
555 | | output.deref() |
556 | | ); |
557 | | assert!( |
558 | | output.len() |
559 | | == serialized_size(&0x1234_5678_90AB_CDEF_1234_5678_90AB_CDEFu128).unwrap() |
560 | | ); |
561 | | assert!(output.len() <= Vec::<u8, SZ>::POSTCARD_MAX_SIZE); |
562 | | } |
563 | | |
564 | | #[derive(Serialize)] |
565 | | struct BasicU8S { |
566 | | st: u16, |
567 | | ei: u8, |
568 | | ote: u128, |
569 | | sf: u64, |
570 | | tt: u32, |
571 | | } |
572 | | |
573 | | impl MaxSize for BasicU8S { |
574 | | const POSTCARD_MAX_SIZE: usize = { |
575 | | u16::POSTCARD_MAX_SIZE |
576 | | + u8::POSTCARD_MAX_SIZE |
577 | | + u128::POSTCARD_MAX_SIZE |
578 | | + u64::POSTCARD_MAX_SIZE |
579 | | + u32::POSTCARD_MAX_SIZE |
580 | | }; |
581 | | } |
582 | | |
583 | | #[test] |
584 | | fn ser_struct_unsigned() { |
585 | | const SZ: usize = BasicU8S::POSTCARD_MAX_SIZE; |
586 | | let input = BasicU8S { |
587 | | st: 0xABCD, |
588 | | ei: 0xFE, |
589 | | ote: 0x1234_4321_ABCD_DCBA_1234_4321_ABCD_DCBA, |
590 | | sf: 0x1234_4321_ABCD_DCBA, |
591 | | tt: 0xACAC_ACAC, |
592 | | }; |
593 | | let output: Vec<u8, SZ> = to_vec(&input).unwrap(); |
594 | | |
595 | | assert_eq!( |
596 | | &[ |
597 | | 0xCD, 0xD7, 0x02, 0xFE, 0xBA, 0xB9, 0xB7, 0xDE, 0x9A, 0xE4, 0x90, 0x9A, 0x92, 0xF4, |
598 | | 0xF2, 0xEE, 0xBC, 0xB5, 0xC8, 0xA1, 0xB4, 0x24, 0xBA, 0xB9, 0xB7, 0xDE, 0x9A, 0xE4, |
599 | | 0x90, 0x9A, 0x12, 0xAC, 0xD9, 0xB2, 0xE5, 0x0A |
600 | | ], |
601 | | output.deref() |
602 | | ); |
603 | | assert!(output.len() == serialized_size(&input).unwrap()); |
604 | | assert!(output.len() <= BasicU8S::POSTCARD_MAX_SIZE); |
605 | | } |
606 | | |
607 | | #[test] |
608 | | fn ser_byte_slice() { |
609 | | let input: &[u8] = &[1u8, 2, 3, 4, 5, 6, 7, 8]; |
610 | | let output: Vec<u8, 9> = to_vec(input).unwrap(); |
611 | | assert_eq!( |
612 | | &[0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08], |
613 | | output.deref() |
614 | | ); |
615 | | assert!(output.len() == serialized_size(&input).unwrap()); |
616 | | |
617 | | let mut input: Vec<u8, 1024> = Vec::new(); |
618 | | for i in 0..1024 { |
619 | | input.push((i & 0xFF) as u8).unwrap(); |
620 | | } |
621 | | let output: Vec<u8, 2048> = to_vec(input.deref()).unwrap(); |
622 | | assert_eq!(&[0x80, 0x08], &output.deref()[..2]); |
623 | | |
624 | | assert_eq!(output.len(), 1026); |
625 | | for (i, val) in output.deref()[2..].iter().enumerate() { |
626 | | assert_eq!((i & 0xFF) as u8, *val); |
627 | | } |
628 | | } |
629 | | |
630 | | #[test] |
631 | | fn ser_str() { |
632 | | let input: &str = "hello, postcard!"; |
633 | | let output: Vec<u8, 17> = to_vec(input).unwrap(); |
634 | | assert_eq!(0x10, output.deref()[0]); |
635 | | assert_eq!(input.as_bytes(), &output.deref()[1..]); |
636 | | assert!(output.len() == serialized_size(&input).unwrap()); |
637 | | |
638 | | let mut input: String<1024> = String::new(); |
639 | | for _ in 0..256 { |
640 | | write!(&mut input, "abcd").unwrap(); |
641 | | } |
642 | | let output: Vec<u8, 2048> = to_vec(input.deref()).unwrap(); |
643 | | assert_eq!(&[0x80, 0x08], &output.deref()[..2]); |
644 | | assert!(String::<1024>::POSTCARD_MAX_SIZE <= output.len()); |
645 | | |
646 | | assert_eq!(output.len(), 1026); |
647 | | for ch in output.deref()[2..].chunks(4) { |
648 | | assert_eq!("abcd", core::str::from_utf8(ch).unwrap()); |
649 | | } |
650 | | } |
651 | | |
652 | | #[test] |
653 | | fn usize_varint_encode() { |
654 | | let mut buf = [0; varint_max::<usize>()]; |
655 | | let res = varint_usize(1, &mut buf); |
656 | | |
657 | | assert_eq!(&[1], res); |
658 | | |
659 | | let res = varint_usize(usize::MAX, &mut buf); |
660 | | |
661 | | // |
662 | | if varint_max::<usize>() == varint_max::<u32>() { |
663 | | assert_eq!(&[0xFF, 0xFF, 0xFF, 0xFF, 0x0F], res); |
664 | | } else if varint_max::<usize>() == varint_max::<u64>() { |
665 | | assert_eq!( |
666 | | &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01], |
667 | | res |
668 | | ); |
669 | | } else { |
670 | | panic!("Update this test for 16/128 bit targets!"); |
671 | | } |
672 | | } |
673 | | |
674 | | #[allow(dead_code)] |
675 | | #[derive(Serialize)] |
676 | | enum BasicEnum { |
677 | | Bib, |
678 | | Bim, |
679 | | Bap, |
680 | | } |
681 | | |
682 | | #[derive(Serialize)] |
683 | | struct EnumStruct { |
684 | | eight: u8, |
685 | | sixt: u16, |
686 | | } |
687 | | |
688 | | #[derive(Serialize)] |
689 | | enum DataEnum { |
690 | | Bib(u16), |
691 | | Bim(u64), |
692 | | Bap(u8), |
693 | | Kim(EnumStruct), |
694 | | Chi { a: u8, b: u32 }, |
695 | | Sho(u16, u8), |
696 | | } |
697 | | |
698 | | #[test] |
699 | | fn enums() { |
700 | | let input = BasicEnum::Bim; |
701 | | let output: Vec<u8, 1> = to_vec(&input).unwrap(); |
702 | | assert_eq!(&[0x01], output.deref()); |
703 | | assert!(output.len() == serialized_size(&input).unwrap()); |
704 | | |
705 | | let input = DataEnum::Bim(u64::MAX); |
706 | | let output: Vec<u8, { 1 + varint_max::<u64>() }> = to_vec(&input).unwrap(); |
707 | | assert_eq!( |
708 | | &[0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01], |
709 | | output.deref() |
710 | | ); |
711 | | assert!(output.len() == serialized_size(&input).unwrap()); |
712 | | |
713 | | let input = DataEnum::Bib(u16::MAX); |
714 | | let output: Vec<u8, { 1 + varint_max::<u16>() }> = to_vec(&input).unwrap(); |
715 | | assert_eq!(&[0x00, 0xFF, 0xFF, 0x03], output.deref()); |
716 | | assert!(output.len() == serialized_size(&input).unwrap()); |
717 | | |
718 | | let input = DataEnum::Bap(u8::MAX); |
719 | | let output: Vec<u8, 2> = to_vec(&input).unwrap(); |
720 | | assert_eq!(&[0x02, 0xFF], output.deref()); |
721 | | assert!(output.len() == serialized_size(&input).unwrap()); |
722 | | |
723 | | let input = DataEnum::Kim(EnumStruct { |
724 | | eight: 0xF0, |
725 | | sixt: 0xACAC, |
726 | | }); |
727 | | let output: Vec<u8, 8> = to_vec(&input).unwrap(); |
728 | | assert_eq!(&[0x03, 0xF0, 0xAC, 0xD9, 0x02], output.deref()); |
729 | | assert!(output.len() == serialized_size(&input).unwrap()); |
730 | | |
731 | | let input = DataEnum::Chi { |
732 | | a: 0x0F, |
733 | | b: 0xC7C7C7C7, |
734 | | }; |
735 | | let output: Vec<u8, 8> = to_vec(&input).unwrap(); |
736 | | assert_eq!(&[0x04, 0x0F, 0xC7, 0x8F, 0x9F, 0xBE, 0x0C], output.deref()); |
737 | | assert!(output.len() == serialized_size(&input).unwrap()); |
738 | | |
739 | | let input = DataEnum::Sho(0x6969, 0x07); |
740 | | let output: Vec<u8, 8> = to_vec(&input).unwrap(); |
741 | | assert_eq!(&[0x05, 0xE9, 0xD2, 0x01, 0x07], output.deref()); |
742 | | assert!(output.len() == serialized_size(&input).unwrap()); |
743 | | } |
744 | | |
745 | | #[test] |
746 | | fn tuples() { |
747 | | let input = (1u8, 10u32, "Hello!"); |
748 | | let output: Vec<u8, 128> = to_vec(&input).unwrap(); |
749 | | assert_eq!( |
750 | | &[1u8, 0x0A, 0x06, b'H', b'e', b'l', b'l', b'o', b'!'], |
751 | | output.deref() |
752 | | ); |
753 | | assert!(output.len() == serialized_size(&input).unwrap()); |
754 | | } |
755 | | |
756 | | #[test] |
757 | | fn bytes() { |
758 | | let x: &[u8; 32] = &[0u8; 32]; |
759 | | let output: Vec<u8, 128> = to_vec(x).unwrap(); |
760 | | assert_eq!(output.len(), 32); |
761 | | assert!(output.len() == serialized_size(&x).unwrap()); |
762 | | assert!(<[u8; 32] as MaxSize>::POSTCARD_MAX_SIZE <= output.len()); |
763 | | |
764 | | let x: &[u8] = &[0u8; 32]; |
765 | | let output: Vec<u8, 128> = to_vec(x).unwrap(); |
766 | | assert_eq!(output.len(), 33); |
767 | | assert!(output.len() == serialized_size(&x).unwrap()); |
768 | | } |
769 | | |
770 | | #[derive(Serialize)] |
771 | | pub struct NewTypeStruct(u32); |
772 | | |
773 | | #[derive(Serialize)] |
774 | | pub struct TupleStruct((u8, u16)); |
775 | | |
776 | | #[test] |
777 | | fn structs() { |
778 | | let input = NewTypeStruct(5); |
779 | | let output: Vec<u8, 1> = to_vec(&input).unwrap(); |
780 | | assert_eq!(&[0x05], output.deref()); |
781 | | assert!(output.len() == serialized_size(&input).unwrap()); |
782 | | |
783 | | let input = TupleStruct((0xA0, 0x1234)); |
784 | | let output: Vec<u8, 3> = to_vec(&input).unwrap(); |
785 | | assert_eq!(&[0xA0, 0xB4, 0x24], output.deref()); |
786 | | assert!(output.len() == serialized_size(&input).unwrap()); |
787 | | } |
788 | | |
789 | | #[derive(Serialize, Deserialize, Eq, PartialEq, Debug)] |
790 | | struct RefStruct<'a> { |
791 | | bytes: &'a [u8], |
792 | | str_s: &'a str, |
793 | | } |
794 | | |
795 | | #[test] |
796 | | fn ref_struct() { |
797 | | let message = "hElLo"; |
798 | | let bytes = [0x01, 0x10, 0x02, 0x20]; |
799 | | let input = RefStruct { |
800 | | bytes: &bytes, |
801 | | str_s: message, |
802 | | }; |
803 | | let output: Vec<u8, 11> = to_vec(&input).unwrap(); |
804 | | |
805 | | assert_eq!( |
806 | | &[0x04, 0x01, 0x10, 0x02, 0x20, 0x05, b'h', b'E', b'l', b'L', b'o',], |
807 | | output.deref() |
808 | | ); |
809 | | assert!(output.len() == serialized_size(&input).unwrap()); |
810 | | } |
811 | | |
812 | | #[test] |
813 | | fn unit() { |
814 | | let output: Vec<u8, 1> = to_vec(&()).unwrap(); |
815 | | assert_eq!(output.len(), 0); |
816 | | assert!(output.len() == serialized_size(&()).unwrap()); |
817 | | } |
818 | | |
819 | | #[test] |
820 | | fn heapless_data() { |
821 | | let mut input: Vec<u8, 4> = Vec::new(); |
822 | | input.extend_from_slice(&[0x01, 0x02, 0x03, 0x04]).unwrap(); |
823 | | let output: Vec<u8, 5> = to_vec(&input).unwrap(); |
824 | | assert_eq!(&[0x04, 0x01, 0x02, 0x03, 0x04], output.deref()); |
825 | | assert!(output.len() == serialized_size(&input).unwrap()); |
826 | | |
827 | | let mut input: String<8> = String::new(); |
828 | | write!(&mut input, "helLO!").unwrap(); |
829 | | let output: Vec<u8, 7> = to_vec(&input).unwrap(); |
830 | | assert_eq!(&[0x06, b'h', b'e', b'l', b'L', b'O', b'!'], output.deref()); |
831 | | assert!(output.len() == serialized_size(&input).unwrap()); |
832 | | |
833 | | let mut input: FnvIndexMap<u8, u8, 4> = FnvIndexMap::new(); |
834 | | input.insert(0x01, 0x05).unwrap(); |
835 | | input.insert(0x02, 0x06).unwrap(); |
836 | | input.insert(0x03, 0x07).unwrap(); |
837 | | input.insert(0x04, 0x08).unwrap(); |
838 | | let output: Vec<u8, 100> = to_vec(&input).unwrap(); |
839 | | assert_eq!( |
840 | | &[0x04, 0x01, 0x05, 0x02, 0x06, 0x03, 0x07, 0x04, 0x08], |
841 | | output.deref() |
842 | | ); |
843 | | assert!(output.len() == serialized_size(&input).unwrap()); |
844 | | } |
845 | | |
846 | | #[test] |
847 | | fn cobs_test() { |
848 | | let message = "hElLo"; |
849 | | let bytes = [0x01, 0x00, 0x02, 0x20]; |
850 | | let input = RefStruct { |
851 | | bytes: &bytes, |
852 | | str_s: message, |
853 | | }; |
854 | | |
855 | | let mut output: Vec<u8, 13> = to_vec_cobs(&input).unwrap(); |
856 | | |
857 | | let sz = cobs::decode_in_place(output.deref_mut()).unwrap(); |
858 | | |
859 | | let x = crate::from_bytes::<RefStruct<'_>>(&output.deref_mut()[..sz]).unwrap(); |
860 | | |
861 | | assert_eq!(input, x); |
862 | | } |
863 | | } |