Hello, I am writing a simple TCP game server using tokio and have a small question. Is it possible to make the following code work with async and not have to use a fully qualified path?
trait ReadPacket<P> {
fn read_packet(&mut self) -> P;
}
#[derive(Clone)]
struct Caller;
#[derive(Debug)]
struct Packet1;
#[derive(Debug)]
struct Packet2;
// normally AsyncReadExt + Unpin instead of Clone, changed for demonstration purpose
impl<T> ReadPacket<Packet1> for T
where T: Clone {
fn read_packet(&mut self) -> Packet1 {
// read data from socket
Packet1 {}
}
}
impl<T> ReadPacket<Packet2> for T
where T: Clone {
fn read_packet(&mut self) -> Packet2 {
Packet2 {}
}
}
#[derive(Debug)]
enum Test {
Packet1(Packet1),
Packet2(Packet2)
}
fn main() {
let mut caller = Caller {};
let test1 = Test::Packet1(caller.read_packet());
let test2 = Test::Packet2(caller.read_packet());
println!("{:?}", test1);
println!("{:?}", test2);
}
This code works fine with "normal" version, but as soon as I make fn read(&mut self) -> P
async I need to change simple Test::Packet1(caller.read())
into Test::Packet1(<Caller as ReadPacket<Packet1>>::read(&mut caller).await)
, which works fine, but is extremely unreadable.
My current recv loop looks something like that:
while let Ok(packet_id) = reader.read_u8().await {
match packet_id {
// here I need to do the weird cast as this doesn't compile
1 => Test::Packet1(reader.read_packet().await),
...
}
}