I'm dealing with a larger project that would like to support both std and no_std crates, and requires minimal but essential io handling.
The blocker is std::io not being available in core::io. I've searched and looked through a lot of comments, posts, github issues, rfcs, etc. but I'm still not sure what is the latest status and what are the near term (next few years) plans. What is the recommended way to approach it?
Choices include:
using some core-io, embedded-io like library, with various degrees of inconvenience,
writing everything sans-io, with various degrees of inconvenience (but works with async, so there's that)
duplicating the codebase and abandoning hopes for no_std/std interop
I'd appreciate your thoughts and some pointers to the latest status of things.
My perspective is that core::error took the initial steps toward making no_stdio possible. Unfortunately, it took about a decade just to get there and the io traits are largely dependent on alloc via std::io::Error. While I would personally be in favor of moving std::io to alloc, I don't know anything about the effort or developer interest in that.
embedded-io and embedded-io-async are the community-supported crates for I/O interfacing. FWIW, the embassy project recommends these and implements the interfaces for UART and TCP.
I guess it depends on how you intend to use them, but maybe you can toggle between std::io and embedded-io trait impls based on a std feature. sans-io is definitely the most future-proof way, though.
I was saying it's impossible, but OK, with a handler for last_os_error and some kind of repr for vectored IO it's at least imaginable.
But I think there's a nicer approach:
stabilize trait aliases with Foo<T=X> bounds (this was proposed and seems to be desired, so it should happen eventually); then we can have an IO error in core with generic error type
add a language feature that trait aliases can add default trait methods
Then it should be doable. Except for impl Read for &[u8] which now returns io::Error and would cause coherence issues since &[u8] is core type. (And would be unavailable in core and it should've been Infallible from the beginning.)
Isn't something like ciborium-io really all that is needed just to get going now? A trait generic over the error.
Since it can have a blanket impl for everything that implements std::io traits, it kind of works? Code that needs to work over no_std and std, can be written using this trait?
Ideally the compatibility the other way around would added in the future, but bandaiding with newtypes might not be too bad for time being.