I'm designing traits for a socket. I'd like to use something from std library but I didn't find any. My idea is so I can create all sorts of sockets and then use like this: my_socket: Box<dyn Socket>
.
I'm also very in doubt about using async or not, so I made 2 versions. Note that I also don't know if it's better to pass a callback to be called when data arrives or if it's ok for the client to poll (in the async case) or block when calling tcp_receive
.
pub type OnTcpSocketData = Arc<dyn Fn(&[u8]) -> Result<usize, SocketReceiveError>>;
pub type OnUdpSocketData = Arc<dyn Fn(&[u8], IpAddr, u16) -> Result<usize, SocketReceiveError>>;
pub trait Socket {
fn set_on_tcp_socket_data(on_tcp_socket_data: OnTcpSocketData);
fn set_on_udp_socket_data(on_tcp_socket_data: OnUdpSocketData);
fn tcp_socket_send(&mut self, data: &[u8]) -> Result<usize, SocketSendError>;
fn udp_socket_send(&mut self, data: &[u8], addr: IpAddr) -> Result<usize, SocketSendError>;
fn tcp_connect(&mut self, addr: IpAddr, port: u16) -> Result<(), SocketConnectionError>;
fn tcp_receive(&mut self, f: &dyn Fn(&[u8])) -> Result<usize,SocketReceiveError>;
fn udp_receive(&mut self, f: &dyn Fn(&[u8], IpAddr, u16)) -> Result<usize,SocketReceiveError>;
}
pub trait SocketAsync {
fn set_on_tcp_socket_data(on_tcp_socket_data: OnTcpSocketData);
fn set_on_udp_socket_data(on_tcp_socket_data: OnUdpSocketData);
fn tcp_socket_send(&mut self, data: &[u8]) -> Pin<Box<dyn Future<Output=Result<usize, SocketSendError>>>>;
fn udp_socket_send(&mut self, data: &[u8], addr: IpAddr) -> Pin<Box<dyn Future<Output=Result<usize, SocketSendError>>>>;
fn tcp_connect(&mut self, addr: IpAddr, port: u16) -> Pin<Box<dyn Future<Output=Result<usize, SocketConnectionError>>>>;
fn tcp_receive(&mut self, f: &dyn Fn(&[u8])) -> Pin<Box<dyn Future<Output=Result<usize,SocketReceiveError>>>>;
fn udp_receive(&mut self, f: &dyn Fn(&[u8], IpAddr, u16)) -> Pin<Box<dyn Future<Output=Result<usize,SocketReceiveError>>>>;
}
I'm trying to take inspiration from Tokio's TcpStream which implements AsyncRead
and AsyncWrite
, which also has there utilities tokio::io::AsyncReadExt - Rust with simple functions like fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>
which looks a lot like my tcP-receive
Am I in a good track?