How to go about writing a async-runtime-agnostic no_std-friendly library

i wasn't aware of the status quo of async/await wrt writing my own library up until now. i'm writing a library for learning, an rtsp server framework, similar to hyper. in that goal, i'd like to be as agnostic as possible wrt the choice of the async runtime the user chooses. i also want to not depend on libstd for helping embedded devs utilize my work, as to not waste human-beings' precious time

since std::io::Error in core is not stabilized yet (moved to core very recently), i don't think there are any libraries with supports for no_std akin to futures allowing me to utilize a set of standardized traits (for Read/Write-like functionality) thus. futures-io would be very nice to have since it is supposed to be the standard way to go about this, but sadly it does not support no_std. so i was thinking if the most sensible way to go about this is to use embassy-io-async? it appears to support adapts for futures (if another library wants to utilize it without not caring about no_std) and tokio (if the application author all together does care about no_std)?

i'm inexperienced in this regard, so i'd highly appreciate experienced library author's/user's opinions on the matter. my goal is to use standardized traits common in the ecosystem and be no_std friendly as much as possible (maybe i'd even have an std feature and use heapless when that's not available)

if there are people with experience with the nightly std::io::Error in core feature, i'd like to hear their experience as well

happy hacking!

I can't speak to specifics of the no-std side, I'm sure others can[1]. I'd give the following advice:

  • split a huge challenge into pieces and start with one - either no-std or an async skeleton. Realistically this probably means starting with async unless you have a clear, meaty, no-std thing[2] to work on.
  • using futures & futures-... crates will keep you agnostic. I've never yet run into a situation with an embedded runtime somewhere in a nested struct (tokio does this sometimes)
  • If in doubt when trying to find how to solve something difficult and specific - roll your own Future as a dedicated type and impl the traits by hand. Then look to how you could shrink it to an async fn, etc... Don't back off from making dedicated types which you then rationalise away when you fully understand the problem you're solving.
  • you'll probably end up with needing some feature-gated mods for std, a no-std core and multiple(?) no-std io options. (I'm guessing here, but I can't see IO being easy to abstract without an OS)

  1. To date I've focussed on runtime-agnostic and have no-std on my todo-list. ↩︎

  2. a very technical term! ↩︎