(Possible pre-pre-RFC) "ReadFrame" + "WriteFrame" Trait?

While working on a DTLS implementation, and looking at a few depending/related projects, i discovered that there's a real absence of a "Framed Reader/Writer", the current Read+Write trait assumes a stream of data, and models reading/writing partial chunks entirely off of that.

However, UdpSocket does not implement Write + Read (for good reason), yet i still would like it to be somewhat generic to address through a trait bound, but that's where i discovered there is no trait bound of this type.

What i'm looking for is something along the lines of "Write/Read either an entire frame/chunk of bytes, or nothing at all", an ethernet/UDP frame, a websocket frame, or another "frame" of data.

In the case of UDP, these frames may be unordered/unreliable, but they would be framed. In the case of WebSockets, they'd be ordered and reliable.

Thus, the only functionality that this trait would give is "I will read/write either one frame of data as I see it.", which is a lot weaker than Read+Write, but could still be helpful, as it guarantees a bound of ordered bytes, outside of which these bounds can arrive in any order. This could make protocols with in-band sequencing (aforementioned DTLS, CoAP, or even TCP/IP on top of Ethernet framing) able to generically use this API.

Has such an API ever been considered? If not, would there be interest in such a thing?

There is a (afaik unused) crate that defines a trait similar to this for async contexts: async-datagram. It's not quite fully general since it is send_to/recv_from so encodes the expectation that a single socket is able to talk to multiple addresses (though I guess you could have type Receiver = () for a WebSocket).

There's also another encoding I've seen used for this in the async world:

Stream<Item = io::Result<impl AsRef<[u8]>>>
 + Sink<impl AsRef<[u8]>, Error = io::Error>

in the sync world this would be the equivalent of something like

Iterator<Item = io::Result<impl AsRef<[u8]>>>
 + FnMut(impl AsRef<[u8]>) -> io::Result<()>
1 Like

Are you looking into something like this? FramedRead in tokio_util::codec - Rust

No, while the name and some of the API do look like what I’m trying to achieve, this is essentially a streamed decoder internim object. I’m specifically looking for a trait which says “this object can give/take chunks of bytes” in the same way the Read trait currently says “this object can give bytes”.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.