Hi!
I can't figure out how to turn a Framed
stream into something that again implements AsyncWrite and AsyncRead.
Here's a minimized version of the code that I'd like to compile (Playground link):
use bytes::Bytes;
use tokio::io::{AsyncRead, AsyncWrite};
use tokio_util::codec::{Decoder, Encoder, Framed};
use tokio_util::io::{SinkWriter, StreamReader};
// takes a stream and wraps it with encryption
// doesn't compile :-(
fn handshake(stream: impl AsyncRead + AsyncWrite) -> impl AsyncWrite + AsyncRead {
SinkWriter::new(StreamReader::new(Framed::new(
stream,
NoiseCodec),
))
}
struct NoiseCodec;
impl<'a> Encoder<&'a [u8]> for NoiseCodec {
type Error = std::io::Error;
fn encode(
&mut self,
item: &'a [u8],
dst: &mut tokio_util::bytes::BytesMut,
) -> std::result::Result<(), Self::Error> {
todo!() // encrypt stuff
}
}
impl Decoder for NoiseCodec {
type Item = Bytes;
type Error = std::io::Error;
fn decode(
&mut self,
src: &mut tokio_util::bytes::BytesMut,
) -> std::result::Result<Option<Self::Item>, Self::Error> {
todo!() // decrypt stuff
}
}
Another attempt at implementing this using futures
' split
function Playground link:
fn handshake(stream: impl AsyncRead + AsyncWrite) -> (impl AsyncWrite, impl AsyncRead) {
let (wr, rd) = Framed::new(
stream, NoiseCodec,
).split();
(SinkWriter::new(wr), StreamReader::new(rd))
}
This also doesn't work due to a lifetime not being general enough.
However this works (Playground link):
fn make_writer(stream: impl AsyncRead + AsyncWrite) -> impl AsyncWrite {
SinkWriter::new(Framed::new(
stream,
NoiseCodec),
)
}
fn make_reader(stream: impl AsyncRead + AsyncWrite) -> impl AsyncRead {
StreamReader::new(Framed::new(
stream,
NoiseCodec),
)
}
But I need to be able to read and write.
Thanks for any help in advance!