Coverage Report

Created: 2026-10-28 07:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}