asynchronous-codec
asynchronous-codec copied to clipboard
[WIP] no_std traits
Hello.
I am trying to use this crate to write a library around a custom TCP based protocol. Said protocol will likely be useful on both web servers and embedded devices (as long as said devices provide some sort of networking and a TCP stream implementation; think embassy-net), so I want to make it as portable as possible.
While I understand it might not be possible for it to be fully portable (e.g. Framed(Read/Write) are not embassy-net compatible, due to embassy-net's TCP stream not being AsyncRead/AsyncWrite compatible), it would still help a great deal if I can at least reuse the encoder and decoder, and just swap out a stream handler.
This PR is my attempt to do this (by getting rid of std::io::Error in encoder and decoder, and following the compiler warnings from there), but I am new to Rust, so I ended up with some errors related to Fuse, and yet occurring in FramedRead/FramedWrite, and I'm not sure how to deal with those yet.
I thought I share the progress so far, to ensure it's even worth pursuing this to its end, or if I should perhaps try to instead refactor async-codec to be splittable (which is the reason I ended here... Because I also need a reader/writer split).
Hi there,
Thanks for upstreaming this. In general I am not opposed to being no-std compliant, unless it adds significant overhead to the crate.
Do you think it makes sense to port parts of async-codec to this crate?
Thanks for upstreaming this. In general I am not opposed to being no-std compliant, unless it adds significant overhead to the crate.
Good to know 👍
Do you think it makes sense to port parts of async-codec to this crate?
Not sure... I kind of like this crate's API better, in that it is simpler to make codecs with it.
At the same time, it seems async-codec allows for the codec to be more directly demanding of the stream handler (i.e. it can tell it "don't invoke me again until you have N more bytes ready in the buffer"), which... maybe... would improve performance. I say maybe, because the bytes still need to be checked anyway... It's just that they are checked by the stream handler, not by the codec... and in practice, the codec still should be defensively checking the length anyway, so... I guess the point is lost, maybe.
I have not tried to implement a no_std compatible framed reader/writer, so maybe async-codec's API is the only way to potentially do it in alloc-free environments (potentially being a keyword, because even async-codec's reader is not no_std compatible; only its codec API is).
I am thinking that instead of porting async-codec, maybe just eliminate Fuse and instead refactor the hierarchy a bit, so that we have reader/writer traits with default implementations that include get_reader()/get_writer() methods, respectively. FramedReader/FramedWriter would only implement the respective trait, and Framed would implement both. In all cases, get_reader()/get_writer() would return "self"... It's just "self" would be different based on the struct.
I do similar gymnastics in my lib, but I'm not sure if that's a good pattern. It gets rid of repetition, but I'm not sure if it introduces some hidden overhead.