How do I make AsyncRead play nice with io::Read custom implemented functions?

I'm creating a TCP server with tokio because I like parallel computing :slight_smile: and I have some custom traits that implement functions for std::io::Read and std::io::Write so I can parse packets:

pub trait VarStringReader {
	fn read_varstring(&mut self) -> Result<String>;
}
impl<R: io::Read> VarStringReader for R {
    fn read_varstring(&mut self) -> Result<String> {
		let length: usize = self.read_varint()?; //see my library variant-encoding (fork of integer-encoding-rs)
		let mut buf = vec![0 as u8; length];
		self.read(&mut buf)?;
		Ok(String::from_utf8_lossy(&buf).to_string())
    }
}

This doesn't work with tokio::io::AsyncRead because AsyncRead doesn't implement std::io::Read. How can I get a synchronous reading (and writing) handler to be able to use my custom functions?

The only real way to do this is to first read the memory into a Vec<u8>, and then pass a &[u8] slice to your VarStringReader, making use of the fact that slices implement std::io::Read.

You could also rewrite it using Tokio's codec feature, which you can read a bit more about here, or perhaps just as an async function operating on an AsyncRead.

2 Likes

Thanks!
I decided to go with Tokio's codec because it makes packet ser/de much easier, I got it working perfectly with FramedRead.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.