enarx / ciborium

CBOR utilities
Other
246 stars 58 forks source link

[Feature, -io]: Optionally implement Writer for heapless::Vec #66

Open chrysn opened 1 year ago

chrysn commented 1 year ago

Is there an existing issue for this?

Description

When working in no_std environments, a heapless::Vec is a popular target to write into: it provides a pre-allocated buffer, but unlike a standard Vec (even with capacity), it is bound in size and thus suitable for stack allocation.

Currently, users need to implement this through a newtype due to the Orphan rule, but it'd be great if one of the two crates that can implement it (ciborium-io and heapless) did, and I think heapless is the more basic crate (so ciborium-io should do it).

Acceptance Criteria

No response

Suggestions for a technical implementation

As far as versions, compatibility and features are concerned, this would in its simplest form target the latest heapless version (there has been a stable 0.7 since const generics landed). This would be an optional, non-default dependency.

I think it'd be prudent to re-export the heapless that's being used, so that users can be sure to use the version of heapless that is actually impl'd.

If heapless does release an incompatible version, it should be possible to impl all of them by depending on different versions of the heapless crate; I think we can cross that bridge when we get there. (Also, who knows, maybe there's a breaking version of ciborium pending at that time anyway, and we can just lockstep).


As an alternative to whack-a-mole'ing heapless (and any other similar crates where a similar request might be done, both in this and other CBOR implementation crates), it might be an option to just go through embedded-io.

chrysn commented 9 months ago

This might be impossible given that there is a impl<T: std::io::Write> Write for T { ... } in place once there is std in use.

How are implementations supposed to be done of Write while keeping features additive? As soon as something enables the std feature, those implementations would conflict with the blanket implementation, would they not?

ahmedcharles commented 8 months ago

heapless::Vec, just like std::vec::Vec does not implement std::io::Write, so there shouldn't be a conflict.

The capnp crate does seem to use embedded-io when std isn't enabled, though this doesn't make it purely additive. Unfortunately, embedded-io doesn't seem to make it obvious how to implement those traits in terms of std ones, so it doesn't enable using embedded-io alone, regardless of whether users are using std or not. Though, perhaps this is the best you can hope for, given all of the constraints.

Note: heapless::Vec doesn't implement embedded-io traits, so this wouldn't result in being able to avoid a newtype, it would just change which traits were implemented on it.