I am working on a client server application where i send messages to / from each as protocol buffers using the rust crate prost. currently i have a generic send_message
function that can take any struct that implements the prost::Message
trait. I'm trying to create a similar function for reading a type that implements prost::Message
. I believe the issue is that decode
which is a method for types that implement prost::Message
is an associated function and not an instance method. the actual instance of the object that implements prost::Message
is created within the function.
Im wondering if there is a way to make a generic read_message
function that can accept any type that implements prost::Message
and use the associated function decode
on that type.
This is my current send_message
function:
pub fn send_message<M>(message: M, stream: &mut TcpStream) -> io::Result<()>
where
M: Message,
{
let length = message.encoded_len() as i32;
let mut buf: Vec<u8> = Vec::with_capacity(length as usize);
message.encode(&mut buf)?;
stream.write_all(&length.to_le_bytes())?;
stream.write_all(&buf)?;
Ok(())
}
and right now i have two read_TYPE_message
functions:
pub fn read_response_message(stream: &mut TcpStream) -> io::Result<message::Response> {
let mut len_buf = [0u8; 4];
stream.read_exact(&mut len_buf)?;
let len = i32::from_le_bytes(len_buf);
println!("Incoming message length: {}", len);
let mut buf = vec![0u8; len as usize];
stream.read_exact(&mut buf)?;
let response = message::Response::decode(&mut buf.as_slice())?;
Ok(response)
}
fn read_request_message(stream: &mut TcpStream) -> io::Result<message::Request> {
let mut len_buf = [0u8; 4];
stream.read_exact(&mut len_buf)?;
let len = i32::from_le_bytes(len_buf);
println!("Incoming message length: {}", len);
let mut buf = vec![0u8; len as usize];
stream.read_exact(&mut buf)?;
let user_input = message::Request::decode(&mut buf.as_slice())?;
Ok(user_input)
}
When i tried the below:
fn read_message<M: Message>(msg: M, stream: &mut TcpStream) -> io::Result<M> {
let mut len_buf = [0u8; 4];
stream.read_exact(&mut len_buf)?;
let len = i32::from_le_bytes(len_buf);
println!("Incoming message length: {}", len);
let mut buf = vec![0u8; len as usize];
stream.read_exact(&mut buf)?;
let pb_msg = msg::decode(&mut buf.as_slice())?;
Ok(pb_msg)
}
I get the error
failed to resolve: use of undeclared crate or module `msg` use of undeclared crate or module `msg`
i was hoping to be able use the function something like this:
let input = read_message(message::Request, &mut stream)?;
let input = read_message(message::Response, &mut stream)?;