diff --git a/source/postcard/README.md b/source/postcard/README.md new file mode 100644 index 0000000..8512457 --- /dev/null +++ b/source/postcard/README.md @@ -0,0 +1,146 @@ +# Postcard + +[![Documentation](https://docs.rs/postcard/badge.svg)](https://docs.rs/postcard) + +Postcard is a `#![no_std]` focused serializer and deserializer for Serde. + +Postcard aims to be convenient for developers in constrained environments, while +allowing for flexibility to customize behavior as needed. + +## Design Goals + +1. Design primarily for `#![no_std]` usage, in embedded or other constrained contexts +2. Support a maximal set of `serde` features, so `postcard` can be used as a drop in replacement +3. Avoid special differences in code between communication code written for a microcontroller or a desktop/server PC +4. Be resource efficient - memory usage, code size, developer time, and CPU time; in that order +5. Allow library users to customize the serialization and deserialization behavior to fit their bespoke needs + +## Format Stability + +As of v1.0.0, `postcard` has a documented and stable wire format. More information about this +wire format can be found in the `spec/` folder of the Postcard repository, or viewed online +at . + +Work towards the Postcard Specification and portions of the Postcard 1.0 Release +were sponsored by Mozilla Corporation. + +## Variable Length Data + +All signed and unsigned integers larger than eight bits are encoded using a [Varint]. +This includes the length of array slices, as well as the discriminant of `enums`. + +For more information, see the [Varint] chapter of the wire specification. + +[Varint]: https://postcard.jamesmunns.com/wire-format.html#varint-encoded-integers + +## Example - Serialization/Deserialization + +Postcard can serialize and deserialize messages similar to other `serde` formats. + +Using the default `heapless` feature to serialize to a `heapless::Vec`: + +```rust +use core::ops::Deref; +use serde::{Serialize, Deserialize}; +use postcard::{from_bytes, to_vec}; +use heapless::Vec; + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] +struct RefStruct<'a> { + bytes: &'a [u8], + str_s: &'a str, +} +let message = "hElLo"; +let bytes = [0x01, 0x10, 0x02, 0x20]; +let output: Vec = to_vec(&RefStruct { + bytes: &bytes, + str_s: message, +}).unwrap(); + +assert_eq!( + &[0x04, 0x01, 0x10, 0x02, 0x20, 0x05, b'h', b'E', b'l', b'L', b'o',], + output.deref() +); + +let out: RefStruct = from_bytes(output.deref()).unwrap(); +assert_eq!( + out, + RefStruct { + bytes: &bytes, + str_s: message, + } +); +``` + +Or the optional `alloc` feature to serialize to an `alloc::vec::Vec`: + +```rust +use core::ops::Deref; +use serde::{Serialize, Deserialize}; +use postcard::{from_bytes, to_allocvec}; +extern crate alloc; +use alloc::vec::Vec; + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] +struct RefStruct<'a> { + bytes: &'a [u8], + str_s: &'a str, +} +let message = "hElLo"; +let bytes = [0x01, 0x10, 0x02, 0x20]; +let output: Vec = to_allocvec(&RefStruct { + bytes: &bytes, + str_s: message, +}).unwrap(); + +assert_eq!( + &[0x04, 0x01, 0x10, 0x02, 0x20, 0x05, b'h', b'E', b'l', b'L', b'o',], + output.deref() +); + +let out: RefStruct = from_bytes(output.deref()).unwrap(); +assert_eq!( + out, + RefStruct { + bytes: &bytes, + str_s: message, + } +); +``` + +## Flavors + +`postcard` supports a system called `Flavors`, which are used to modify the way +postcard serializes or processes serialized data. These flavors act as "plugins" or "middlewares" +during the serialization or deserialization process, and can be combined to obtain complex protocol formats. + +See the documentation of the `ser_flavors` or `de_flavors` modules for more information on usage. + +## Setup - `Cargo.toml` + +Don't forget to add [the `no-std` subset](https://serde.rs/no-std.html) of `serde` along with `postcard` to the `[dependencies]` section of your `Cargo.toml`! + +```toml +[dependencies] +postcard = "1.0.0" + +# By default, `serde` has the `std` feature enabled, which makes it unsuitable for embedded targets +# disabling default-features fixes this +serde = { version = "1.0.*", default-features = false } +``` + +## License + +Licensed under either of + +- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or + ) +- MIT license ([LICENSE-MIT](LICENSE-MIT) or ) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. diff --git a/source/postcard/src/lib.rs b/source/postcard/src/lib.rs index 98f61f5..9fafa00 100644 --- a/source/postcard/src/lib.rs +++ b/source/postcard/src/lib.rs @@ -1,6 +1,6 @@ #![cfg_attr(not(any(test, feature = "use-std")), no_std)] #![warn(missing_docs)] -#![cfg_attr(not(doctest), doc = include_str!("../../../README.md"))] +#![cfg_attr(not(doctest), doc = include_str!("../README.md"))] #![cfg_attr(docsrs, feature(doc_cfg))] pub mod accumulator;