How to store bytes from Read trait in a struct

Hi all,

I'm in the process of learning Rust and for faster adopting of the new language syntax etc I'm rewriting the code of a custom C++ library. This library among other things includes the functionality to exchange data via TCP sockets. While I managed to get the communication up and running, I ran into some obstacles changing the code a little bit.

Up until now I used the following code to read from a socket:

let mut stream = TcpStream::connect_timeout(&socket_addr, Duration::from_secs(con_timeout))?;

// some other unimport code following

// TcpPkgHeader (10 Bytes in size) is a custom struct to handle the communication between clients and the server
let mut buffer = [0; TcpPkgHeader::net_size()];
let bytes_read = stream.read(&mut buffer);

// from now on, the buffer contains the wanted data (bytes_read = 10)
// I am now able to create a struct from the buffer data

But because of the fact, that I want to make the use of the new Rust library in terms of naming conventions/types as close as possible to the C++ one, I introduced a new struct to the library: Buffer.
I want to store the binary data inside this struct with also some additional values (some of them will be added in the near future). Now the code from above looks like this:

let mut stream = TcpStream::connect_timeout(&socket_addr, Duration::from_secs(con_timeout))?;

// some other unimport code following

// TcpPkgHeader (10 Bytes in size) is a custom struct to handle the communication between clients and the server
let mut buffer = Buffer::new(TcpPkgHeader::net_size());
let bytes_read = stream.read(&mut buffer);

// from now on, the buffer doesn't contain the wanted data (bytes_read = 0)

The implementation of Buffer is the following:

use std::fmt;
use std::ops;
use std::ops::{Deref, DerefMut};

#[derive(Clone)]
pub struct Buffer {
    data: Vec<u8>,
    // max data size
    len: usize,
    // actual data size
    data_len: usize,
}

impl Buffer {
    pub fn new(len: usize) -> Self {
        Self {
            data: Vec::new(),
            len,
            data_len: 0,
        }
    }

    pub fn from_bytes(bytes: Vec<u8>) -> Self {
        let size = bytes.len();
        Self {
            data: bytes,
            len: size,
            // we have to expect, that the length of the slice is equivalent to the data length
            data_len: size,
        }
    }

    pub fn len(&self) -> usize {
        self.len
    }

    pub fn data_len(&self) -> usize {
        self.data_len
    }

    pub fn to_bytes(&self) -> &[u8] {
        &self.data[..self.data_len]
    }
}

// impl ops::Add<Buffer> for Buffer {
//     type Output = Self;
//     fn add(self, another: Buffer) -> Self {
//         Self {
//             data: vec![&self.data, ],
//             len: self.len + another.len,
//             data_len: self.data_len + another.data_len,
//         }
//     }
// }

impl ops::AddAssign<Buffer> for Buffer {
    fn add_assign(&mut self, another: Buffer) {
        self.data.extend_from_slice(&another.data);
        self.len = self.len + another.len;
        self.data_len = self.data_len + another.data_len;
    }
}

impl fmt::Display for Buffer {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "Buffer {{ data: {:X?}, len: {}, data_len: {} }}",
            self.data, self.len, self.data_len
        )
    }
}

impl Deref for Buffer {
    type Target = [u8];

    fn deref(&self) -> &Self::Target {
        &self.data
    }
}

impl DerefMut for Buffer {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.data[..]
    }
}

My thinking was, that if I implement the DerefMut/Deref traits for Buffer, TcpStream::read() will be able to store the data inside Buffer.data. Unfortunately it doesn't work this way.
I would be thankful for an explanation on what I understood wrong here and how can I make the data storing for the struct work in this case?

Best regards

To use the read method like this, you need to first increase the size of the vector so you can get a &mut [u8] that the call is able to write to. As is, you are getting an &mut [u8] of length zero, so no data is written.

oh my... why haven't I thought of that myself. I assume this is because the byte slice is only a reference to a part of the vec, which itself cannot grow in size. Thank you very much!

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.