Skip to content

[RFC] Standardize binary serialization crate when precise control over layout is needed #686

@RobertZ2011

Description

@RobertZ2011

Background

Converting between a series of bytes and a struct is a commonly used feature in embedded development. Usually, the bytes have a specific format and layout dictated by a datasheet or spec. It's possible to do this manually with a combination of [repr(C)], and unsafe code, but it's not very ergonomic. There are numerous Rust crates that provide this functionality with a nice, safe API. Type-C code, in particular, currently uses bincode for this functionality, but it's marked as no longer maintained on Github, and wasn't ideal for the task. We want to migrate away and standardize on a new crate.

Proposal

This RFC proposes zerocopy as the standard crate. This crate provides traits like FromBytes, FromZeros, and TryFromBytes. These traits and their associated derive macros should provide the needed functionality. Zerocopy also supports endianness, which is desired to allow ODP to support a wide range of hardware. Endianness is also a property of the struct itself and I think that matches the typical use case better.

Alternatives Considered

  • Bytemuck is very similar to zerocopy in the traits and API it provides but doesn't have support for endianness.
  • Staying with Bincode is another option, but its default behavior is to serialize into its own binary format and custom code is frequently needed to match the required layout.
  • Binary_serde is a strong contender. However, zerocopy is focused on this specific use case, while serde is a more general serialization framework. As a result, Zerocopy provides a richer set of traits that are better suited for binary data. Endianness is provided as an argument to decode/encode with binary_serde instead of being a property of the struct itself. binary_serde doesn't support dynamically sized types like &[T]. This ultimately makes it partially incompatible with the broader serde environment. Code would have to be specifically written for binary_serde, negating some of the benefit of using serde.

Metadata

Metadata

Assignees

Labels

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions