bincode icon indicating copy to clipboard operation
bincode copied to clipboard

Implement support for conversion to / from heapless::Vec

Open petekubiak opened this issue 1 year ago • 4 comments

I am working on a no_std embedded comms stack which talks to devices running C applications. The stack uses heapless::Vecs to handle the byte streams being sent and received, and I would like to use bincode to perform the conversion to / from Rust structures.

Right now, in order to do this I have to create a wrapper type around the heapless::Vec in order to implement bincode's Writer and Reader traits. It seems like this is a common enough pairing that it would make sense to have these traits implemented for heapless::Vec by default, or at least available through a feature, rather than having to re-implement for each new project working in this space.

I am inclined to think that the implementation should be included within bincode, possibly alongside an implementation for std::Vec too, however I have created an equivalent issue on the heapless repo in case the community thinks that it would make more sense for the implementation to live there.

petekubiak avatar Nov 29 '24 14:11 petekubiak

Apparently there's precedent for the implementation to live in the serialiser's crate. Both postcard and cbor_smol do this.

petekubiak avatar Nov 29 '24 17:11 petekubiak

I've modified the title of this issue to be more general, as I want to also encompass the option of encode_into_vec and decode_from_vec functions as an alternative to implementing the Reader and Writer traits on heapless::Vec. This is how postcard does it.

An encode_into_allocvec and decode_from_allocvec could also be implemented to support the standard Vec.

petekubiak avatar Nov 30 '24 03:11 petekubiak

See also https://github.com/bincode-org/bincode/issues/643

One solution is to mark your field with #[bincode(with_serde)], which will fall back to the serde implementation.

We'd rather not have crate-specific implementations in bincode if we can help it

VictorKoenders avatar Dec 01 '24 07:12 VictorKoenders

This isn't for encoding / decoding a field containing a vec, but rather to populate a vec with the encoded data (or to take a vec containing a byte stream and decode it into the corresponding data structure).

Currently bincode only works with slices or its own Reader and Writer traits, so in order to work with Vecs, (handy when the length of the byte stream is variable), I have to wrap the Vec so that I can implement the Writer trait on it.

As a side note: the current format of the Reader trait is such that I would have to do an unnecessary copy of the data, so I end with an asymmetric implementation where I use encode_into_writer for encoding and decode_from_slice (passing in vec.as_slice) for reading.

I have to implement this wrapper in every project I use bincode for, as using a heapless::Vec to hold the data is much more ergonomic than dealing with a bare array buffer where I must keep track of the byte stream length manually.

This seems like such a common pairing that it would make sense to have the option to deal with byte streams packaged as Vecs rather than byte slices.

I would also argue that this barely qualifies as a crate-specific implementation: alloc::Vec is part of the standard library, and heapless::Vec is simply the most widely used no_std implementation of a standard Vec. To be honest, the main reason I've been going on about heapless::Vec so much is that I work in the embedded space most of the time and most of my projects are no_std.

petekubiak avatar Dec 01 '24 11:12 petekubiak

Would love this feature. I use bincode a lot on PC applications, and am now trying to apply it to embedded. Is Postcard the move instead for embedded?

David-OConnor avatar Jun 26 '25 13:06 David-OConnor

We are not interested in adding a heapless::Vec implementation in bincode. Maybe the heapless maintainers is willing to add bincode as a feature on their repository.

VictorKoenders avatar Jul 01 '25 09:07 VictorKoenders

https://github.com/rust-embedded/heapless/issues/519

It seems we are at an impasse. I can write a third party integration crate if we have to, but would prefer to resolve this through diplomacy!

David-OConnor avatar Jul 18 '25 16:07 David-OConnor

If I may give an argument for why it makes sense to have the implementation here: bincode currently provides implementations for the standard collections, and covers a use case which is particularly common in the no_std (embedded) space. My experience is that heapless is the de facto collections crate for no_std and exists in practically every no_std project I've encountered, so supporting conversions to heapless collection types in bincode makes sense to sit alongside the std counterparts.

petekubiak avatar Jul 18 '25 17:07 petekubiak