postcard/
lib.rs

1#![cfg_attr(not(any(test, feature = "use-std")), no_std)]
2#![warn(missing_docs)]
3#![cfg_attr(not(doctest), doc = include_str!("../README.md"))]
4#![cfg_attr(docsrs, feature(doc_cfg))]
5
6pub mod accumulator;
7mod byte_array;
8mod de;
9
10mod eio;
11
12mod error;
13pub mod fixint;
14mod ser;
15mod varint;
16
17// Still experimental! Don't make pub pub.
18pub(crate) mod max_size;
19
20/// # Experimental Postcard Features
21///
22/// Items inside this module require various feature flags, and are not
23/// subject to SemVer stability. Items may be removed or deprecated at
24/// any point.
25///
26/// ## Derive
27///
28/// The `experimental-derive` feature enables one experimental feature:
29///
30/// * Max size calculation
31///
32/// ### Max Size Calculation
33///
34/// This features enables calculation of the Max serialized size of a message as
35/// an associated `usize` constant called `POSTCARD_MAX_SIZE`. It also provides a
36/// `#[derive(MaxSize)]` macro that can be used for calculating user types.
37///
38/// This is useful for determining the maximum buffer size needed when receiving
39/// or sending a message that has been serialized.
40///
41/// NOTE: This only covers the size of "plain" flavored messages, e.g. not with COBS
42/// or any other Flavors applied. The overhead for these flavors must be calculated
43/// separately.
44///
45/// Please report any missing types, or any incorrectly calculated values.
46///
47/// ### Message Schema Generation
48///
49/// This now lives in the `postcard-schema` crate.
50pub mod experimental {
51    /// Compile time max-serialization size calculation
52    #[cfg(feature = "experimental-derive")]
53    #[cfg_attr(docsrs, doc(cfg(feature = "experimental-derive")))]
54    pub mod max_size {
55        // NOTE: This is the trait...
56        pub use crate::max_size::MaxSize;
57        // NOTE: ...and this is the derive macro
58        pub use postcard_derive::MaxSize;
59    }
60
61    pub use crate::ser::serialized_size;
62}
63
64pub use byte_array::FixedSizeByteArray;
65pub use de::deserializer::Deserializer;
66pub use de::flavors as de_flavors;
67pub use de::{from_bytes, from_bytes_cobs, take_from_bytes, take_from_bytes_cobs};
68pub use error::{Error, Result};
69pub use ser::flavors as ser_flavors;
70pub use ser::{serialize_with_flavor, serializer::Serializer, to_extend, to_slice, to_slice_cobs};
71
72#[cfg(feature = "heapless")]
73pub use ser::{to_vec, to_vec_cobs};
74
75#[cfg(any(feature = "embedded-io-04", feature = "embedded-io-06"))]
76pub use ser::to_eio;
77
78#[cfg(any(feature = "embedded-io-04", feature = "embedded-io-06"))]
79pub use de::from_eio;
80
81#[cfg(feature = "use-std")]
82pub use ser::{to_io, to_stdvec, to_stdvec_cobs};
83
84#[cfg(feature = "use-std")]
85pub use de::from_io;
86
87#[cfg(feature = "alloc")]
88pub use ser::{to_allocvec, to_allocvec_cobs};
89
90#[cfg(feature = "use-crc")]
91pub use {
92    de::{from_bytes_crc32, take_from_bytes_crc32},
93    ser::to_slice_crc32,
94};
95
96#[cfg(all(feature = "use-crc", feature = "heapless"))]
97pub use ser::to_vec_crc32;
98
99#[cfg(all(feature = "use-crc", feature = "use-std"))]
100pub use ser::to_stdvec_crc32;
101
102#[cfg(all(feature = "use-crc", feature = "alloc"))]
103pub use ser::to_allocvec_crc32;
104
105#[cfg(test)]
106mod test {
107    #[test]
108    fn varint_boundary_canon() {
109        let x = u32::MAX;
110        let mut buf = [0u8; 5];
111        let used = crate::to_slice(&x, &mut buf).unwrap();
112        let deser: u32 = crate::from_bytes(used).unwrap();
113        assert_eq!(deser, u32::MAX);
114        assert_eq!(used, &mut [0xFF, 0xFF, 0xFF, 0xFF, 0x0F]);
115        let deser: Result<u32, crate::Error> = crate::from_bytes(&[0xFF, 0xFF, 0xFF, 0xFF, 0x1F]);
116        assert_eq!(deser, Err(crate::Error::DeserializeBadVarint));
117    }
118
119    #[test]
120    fn signed_int128() {
121        let x = -19490127978232325886905073712831_i128;
122        let mut buf = [0u8; 32];
123        let used = crate::to_slice(&x, &mut buf).unwrap();
124        let deser: i128 = crate::from_bytes(used).unwrap();
125        assert_eq!(deser, x);
126    }
127}