use crate::error::WebsocketError;
use crate::frame::{Frame, Opcode};
use crate::message::Message;
use crate::restion::Restion;
use std::io::{Read, Write};
use std::net::TcpStream;
pub struct WebsocketStream<T>
where
T: Read + Write,
{
stream: T,
closed: bool,
}
impl<T> WebsocketStream<T>
where
T: Read + Write,
{
pub fn new(stream: T) -> Self {
Self {
stream,
closed: false,
}
}
pub fn recv(&mut self) -> Result<Message, WebsocketError> {
let message = Message::from_stream(&mut self.stream);
if let Err(WebsocketError::ConnectionClosed) = message {
self.closed = true;
}
message
}
pub fn send(&mut self, message: Message) -> Result<(), WebsocketError> {
self.stream
.write_all(&message.to_bytes())
.map_err(|_| WebsocketError::WriteError)
}
pub fn inner(&mut self) -> &mut T {
&mut self.stream
}
}
impl WebsocketStream<TcpStream> {
pub fn recv_nonblocking(&mut self) -> Restion<Message, WebsocketError> {
let message = Message::from_stream_nonblocking(&mut self.stream);
if let Restion::Err(WebsocketError::ConnectionClosed) = message {
self.closed = true;
}
message
}
}
impl<T> Drop for WebsocketStream<T>
where
T: Read + Write,
{
fn drop(&mut self) {
if !self.closed {
self.stream
.write_all(Frame::new(Opcode::Close, Vec::new()).as_ref())
.ok();
}
}
}