Search code examples
rustrust-tokio

How do I peek a big endian value from bytes::BytesMut?


I'm converting some of my old code into futures async/await style and have hit a problem.

I'm using the tokio_util crate as I'm dealing with a framed protocol with the Encoder and Decoder traits from this crate.

For the Decoder, I need to peek at the first 2 bytes of the passed bytes::BytesMut struct as these bytes hold the length of the frame. However the BytesMut struct does not easily allow this. My function is:

impl Decoder for MyCodec {
    type Item = ServerMessage;
    type Error = io::Error;

    fn decode(&mut self, buf: &mut BytesMut) -> io::Result<Option<ServerMessage>> {
        if buf.len() <= 2 {
            return Ok(None);
        };

The next step will occur if at least 2 bytes are in buf and these should be read in big endian format to proceed with the decoder. Trouble is I can't see how to do that with a BytesMut structure.


Solution

  • After a bit of experimentation I think this may be the optimal way to do this. From the standard library documentation it says "When starting from a slice rather than an array, fallible conversion APIs can be used" under the "from_be_bytes" function.

    use bytes::BytesMut;
    use std::convert::TryInto;
    
    impl Decoder for MyCodec {
        type Item = ServerMessage;
        type Error = io::Error;
    
        fn decode(&mut self, buf: &mut BytesMut) -> io::Result<Option<ServerMessage>> {
            if buf.len() <= 2 {
                return Ok(None);
            };
    
            let frame_size = u16::from_be_bytes(buf[..2].try_into().unwrap());
    
            ...
         }
    }