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