use std::{ffi::os_str::Display, fmt::Debug, sync::Arc};
use corlib::text::AsStr;
use fastwebsockets::{upgrade::{IncomingUpgrade, UpgradeFut}, WebSocket};
use highly_sendable::text::SendableText;
use hyper::upgrade::Upgraded;
use hyper_util::rt::TokioIo;
use thiserror::Error;
use super::{OwnedFrame, WebSocketReader};
pub enum WebSocketActorInputMessage {
NewConnection(WebSocket<TokioIo<Upgraded>>), Disconnect,
DisconnectNow,
WriteFrame(OwnedFrame),
}
impl WebSocketActorInputMessage
{
pub fn is_new_connection(&self) -> bool
{
matches!(self, WebSocketActorInputMessage::NewConnection(_))
}
pub fn is_disconnect(&self) -> bool
{
matches!(self, WebSocketActorInputMessage::Disconnect)
}
pub fn is_disconnect_now(&self) -> bool
{
matches!(self, WebSocketActorInputMessage::DisconnectNow)
}
pub fn is_write_frame(&self) -> bool
{
matches!(self, WebSocketActorInputMessage::WriteFrame(_))
}
}
impl Debug for WebSocketActorInputMessage
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::NewConnection(arg0) => f.debug_tuple("NewConnection").finish(), Self::Disconnect => write!(f, "Disconnect"),
Self::DisconnectNow => write!(f, "DisconnectNow"),
Self::WriteFrame(arg0) => f.debug_tuple("WriteFrame").field(arg0).finish(),
}
}
}
#[derive(Debug)]
pub enum WebSocketWorkerActorInputMessage
{
Disconnect,
DisconnectNow,
WriteFrame(OwnedFrame),
}
impl WebSocketWorkerActorInputMessage
{
pub fn is_disconnect(&self) -> bool
{
matches!(self, WebSocketWorkerActorInputMessage::Disconnect)
}
pub fn is_disconnect_now(&self) -> bool
{
matches!(self, WebSocketWorkerActorInputMessage::DisconnectNow)
}
pub fn is_write_frame(&self) -> bool
{
matches!(self, WebSocketWorkerActorInputMessage::WriteFrame(_))
}
pub fn into_web_socket_actor_input_message<T>(self) -> WebSocketActorInputMessage {
match self
{
WebSocketWorkerActorInputMessage::Disconnect => WebSocketActorInputMessage::Disconnect,
WebSocketWorkerActorInputMessage::DisconnectNow => WebSocketActorInputMessage::DisconnectNow,
WebSocketWorkerActorInputMessage::WriteFrame(owned_frame) => WebSocketActorInputMessage::WriteFrame(owned_frame)
}
}
}
#[derive(Error, Debug, Clone)]
pub enum NonConnectionError
{
#[error("An empty URL was provided.")]
EmptyUrlProvided,
#[error("URL parse error: {0}")]
UrlParseError(Arc<str>), #[error("Handshake error: {0}")]
HandshakeError(Arc<str>), #[error("Not connected")]
NotConnected
}
impl NonConnectionError
{
pub fn is_empty_url_provided(&self) -> bool
{
matches!(self, NonConnectionError::EmptyUrlProvided)
}
pub fn is_url_parse_error(&self) -> bool
{
matches!(self, NonConnectionError::UrlParseError(_))
}
pub fn is_handshake_error(&self) -> bool
{
matches!(self, NonConnectionError::HandshakeError(_))
}
pub fn is_not_connected(&self) -> bool
{
matches!(self, NonConnectionError::NotConnected)
}
}
#[derive(Debug)]
pub enum WebSocketActorOutputMessage
{
NewConnection,
ConnectionError(SendableText), NonConnectionError(NonConnectionError), Disconnecting, Disconnected, NotConnected, PongFrameSent,
CloseFrameSent,
ReadFrame(OwnedFrame),
CloseWindowElapsed
}
impl WebSocketActorOutputMessage
{
pub fn is_new_connection(&self) -> bool
{
matches!(self, WebSocketActorOutputMessage::NewConnection)
}
pub fn is_connection_error(&self) -> bool
{
matches!(self, WebSocketActorOutputMessage::ConnectionError(_))
}
pub fn is_non_connection_error(&self) -> bool
{
matches!(self, WebSocketActorOutputMessage::NonConnectionError(_))
}
pub fn is_disconnecting(&self) -> bool
{
matches!(self, WebSocketActorOutputMessage::Disconnecting)
}
pub fn is_disconnected(&self) -> bool
{
matches!(self, WebSocketActorOutputMessage::Disconnected)
}
pub fn is_pong_frame_sent(&self) -> bool
{
matches!(self, WebSocketActorOutputMessage::PongFrameSent)
}
pub fn is_close_frame_sent(&self) -> bool
{
matches!(self, WebSocketActorOutputMessage::CloseFrameSent)
}
pub fn is_read_frame(&self) -> bool
{
matches!(self, WebSocketActorOutputMessage::ReadFrame(_))
}
pub fn is_close_window_elapsed(&self) -> bool
{
matches!(self, WebSocketActorOutputMessage::CloseWindowElapsed)
}
pub fn try_get_control_message(&self) -> Option<WebSocketActorControlMessage>
{
match self
{
WebSocketActorOutputMessage::NewConnection => Some(WebSocketActorControlMessage::NewConnection),
WebSocketActorOutputMessage::ConnectionError(sendable_text) => Some(WebSocketActorControlMessage::ConnectionError(sendable_text.clone())),
WebSocketActorOutputMessage::NonConnectionError(non_connection_error) => Some(WebSocketActorControlMessage::NonConnectionError(non_connection_error.clone())),
WebSocketActorOutputMessage::Disconnecting => Some(WebSocketActorControlMessage::Disconnecting),
WebSocketActorOutputMessage::Disconnected => Some(WebSocketActorControlMessage::Disconnected),
WebSocketActorOutputMessage::NotConnected => Some(WebSocketActorControlMessage::NotConnected),
WebSocketActorOutputMessage::PongFrameSent => Some(WebSocketActorControlMessage::PongFrameSent),
WebSocketActorOutputMessage::CloseFrameSent=> Some(WebSocketActorControlMessage::CloseFrameSent),
WebSocketActorOutputMessage::ReadFrame(_) => None,
WebSocketActorOutputMessage::CloseWindowElapsed => Some(WebSocketActorControlMessage::CloseWindowElapsed)
}
}
pub fn try_get_worker_message<T>(&self) -> Option<WebSocketActorWorkerMessage<T>>
{
match self
{
WebSocketActorOutputMessage::NewConnection => Some(WebSocketActorWorkerMessage::NewConnection),
WebSocketActorOutputMessage::ConnectionError(_sendable_text) => Some(WebSocketActorWorkerMessage::Disconnected),
WebSocketActorOutputMessage::NonConnectionError(_sendable_text) => None,
WebSocketActorOutputMessage::Disconnecting => Some(WebSocketActorWorkerMessage::Disconnecting),
WebSocketActorOutputMessage::Disconnected => Some(WebSocketActorWorkerMessage::Disconnected),
WebSocketActorOutputMessage::NotConnected => None,
WebSocketActorOutputMessage::PongFrameSent => None,
WebSocketActorOutputMessage::CloseFrameSent => None,
WebSocketActorOutputMessage::ReadFrame(_owned_frame) => None,
WebSocketActorOutputMessage::CloseWindowElapsed => Some(WebSocketActorWorkerMessage::Disconnected)
}
}
pub fn try_into_worker_frame_message(self) -> Option<WebSocketActorWorkerFrameMessage>
{
match self
{
WebSocketActorOutputMessage::NewConnection => Some(WebSocketActorWorkerFrameMessage::NewConnection),
WebSocketActorOutputMessage::ConnectionError(_sendable_text) => Some(WebSocketActorWorkerFrameMessage::Disconnected),
WebSocketActorOutputMessage::NonConnectionError(_sendable_text) => None,
WebSocketActorOutputMessage::Disconnecting => Some(WebSocketActorWorkerFrameMessage::Disconnecting),
WebSocketActorOutputMessage::Disconnected => Some(WebSocketActorWorkerFrameMessage::Disconnected),
WebSocketActorOutputMessage::NotConnected => None,
WebSocketActorOutputMessage::PongFrameSent => None,
WebSocketActorOutputMessage::CloseFrameSent => None,
WebSocketActorOutputMessage::ReadFrame(owned_frame) => Some(WebSocketActorWorkerFrameMessage::ReadFrame(owned_frame)),
WebSocketActorOutputMessage::CloseWindowElapsed => Some(WebSocketActorWorkerFrameMessage::Disconnected)
}
}
}
#[derive(Debug)]
pub enum WebSocketActorControlMessage
{
NewConnection,
ConnectionError(SendableText),
NonConnectionError(NonConnectionError), Disconnecting,
Disconnected,
NotConnected,
PongFrameSent,
CloseFrameSent,
CloseWindowElapsed
}
impl WebSocketActorControlMessage
{
pub fn is_new_connection(&self) -> bool
{
matches!(self, WebSocketActorControlMessage::NewConnection)
}
pub fn is_connection_error(&self) -> bool
{
matches!(self, WebSocketActorControlMessage::ConnectionError(_))
}
pub fn is_non_connection_error(&self) -> bool
{
matches!(self, WebSocketActorControlMessage::NonConnectionError(_))
}
pub fn is_disconnecting(&self) -> bool
{
matches!(self, WebSocketActorControlMessage::Disconnecting)
}
pub fn is_disconnected(&self) -> bool
{
matches!(self, WebSocketActorControlMessage::Disconnected)
}
pub fn is_pong_frame_sent(&self) -> bool
{
matches!(self, WebSocketActorControlMessage::PongFrameSent)
}
pub fn is_close_frame_sent(&self) -> bool
{
matches!(self, WebSocketActorControlMessage::CloseFrameSent)
}
pub fn is_close_window_elapsed(&self) -> bool
{
matches!(self, WebSocketActorControlMessage::CloseWindowElapsed)
}
}
#[derive(Debug)]
pub enum WebSocketActorWorkerFrameMessage
{
NewConnection,
Disconnecting,
Disconnected,
ReadFrame(OwnedFrame)
}
impl WebSocketActorWorkerFrameMessage
{
pub fn is_new_connection(&self) -> bool
{
matches!(self, WebSocketActorWorkerFrameMessage::NewConnection)
}
pub fn is_disconnecting(&self) -> bool
{
matches!(self, WebSocketActorWorkerFrameMessage::Disconnecting)
}
pub fn is_disconnected(&self) -> bool
{
matches!(self, WebSocketActorWorkerFrameMessage::Disconnected)
}
pub fn is_read_frame(&self) -> bool
{
matches!(self, WebSocketActorWorkerFrameMessage::ReadFrame(_))
}
}
pub enum WebSocketActorWorkerMessage<T>
{
NewConnection,
Disconnecting,
Disconnected,
WorkInfo(T)
}
impl<T> WebSocketActorWorkerMessage<T>
{
pub fn is_new_connection(&self) -> bool
{
matches!(self, WebSocketActorWorkerMessage::NewConnection)
}
pub fn is_disconnecting(&self) -> bool
{
matches!(self, WebSocketActorWorkerMessage::Disconnecting)
}
pub fn is_disconnected(&self) -> bool
{
matches!(self, WebSocketActorWorkerMessage::Disconnected)
}
pub fn is_work_info(&self) -> bool
{
matches!(self, WebSocketActorWorkerMessage::WorkInfo(_))
}
}
impl<T> Debug for WebSocketActorWorkerMessage<T>
where T: Debug
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::NewConnection => write!(f, "NewConnection"),
Self::Disconnecting => write!(f, "Disconnecting"),
Self::Disconnected => write!(f, "Disconnected"),
Self::WorkInfo(arg0) => f.debug_tuple("WorkInfo").field(arg0).finish(),
}
}
}
pub enum ReadWebSocketActorInputMessage
{
NewConnection(WebSocketReader),
Disconnecting,
Disconnect
}
impl ReadWebSocketActorInputMessage
{
pub fn is_new_connection(&self) -> bool
{
matches!(self, ReadWebSocketActorInputMessage::NewConnection(_))
}
pub fn is_disconnecting(&self) -> bool
{
matches!(self, ReadWebSocketActorInputMessage::Disconnecting)
}
pub fn is_disconnect(&self) -> bool
{
matches!(self, ReadWebSocketActorInputMessage::Disconnect)
}
}
impl Debug for ReadWebSocketActorInputMessage
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::NewConnection(arg0) => f.debug_tuple("NewConnection").finish(), Self::Disconnecting => write!(f, "Disconnecting"),
Self::Disconnect => write!(f, "Disconnect"),
}
}
}
#[derive(Debug)]
pub enum ReadWebSocketActorOutputMessage
{
ReadFrame(OwnedFrame), Disconnected,
}
impl ReadWebSocketActorOutputMessage
{
pub fn is_read_frame(&self) -> bool
{
matches!(self, ReadWebSocketActorOutputMessage::ReadFrame(_))
}
pub fn is_disconnected(&self) -> bool
{
matches!(self,ReadWebSocketActorOutputMessage::Disconnected)
}
}
#[derive(Debug)]
pub enum WebSocketWriterActorInternalMessage {
ConnectionError, NonConnectionError, Disconnected,
NotConnected,
WebSocketReaderActorChannelSenderClosed,
WebSocketReaderActorChannelReceiverClosed,
ActorChannelSenderClosed,
ActorChannelReceiverClosed
}
impl WebSocketWriterActorInternalMessage {
pub fn is_connection_error(&self) -> bool
{
matches!(self, WebSocketWriterActorInternalMessage::ConnectionError)
}
pub fn is_non_connection_error(&self) -> bool
{
matches!(self, WebSocketWriterActorInternalMessage::NonConnectionError)
}
pub fn is_disconnected(&self) -> bool
{
matches!(self, WebSocketWriterActorInternalMessage::Disconnected)
}
pub fn is_not_connected(&self) -> bool
{
matches!(self, WebSocketWriterActorInternalMessage::NotConnected)
}
pub fn is_web_socket_reader_actor_channel_sender_closed(&self) -> bool
{
matches!(self, WebSocketWriterActorInternalMessage::WebSocketReaderActorChannelSenderClosed)
}
pub fn is_web_socket_reader_actor_channel_receiver_closed(&self) -> bool
{
matches!(self, WebSocketWriterActorInternalMessage::WebSocketReaderActorChannelReceiverClosed)
}
pub fn is_actor_channel_sender_closed(&self) -> bool
{
matches!(self, WebSocketWriterActorInternalMessage::ActorChannelSenderClosed)
}
pub fn is_actor_channel_receiver_closed(&self) -> bool
{
matches!(self, WebSocketWriterActorInternalMessage::ActorChannelReceiverClosed)
}
pub fn should_continue(&self) -> bool
{
match self
{
WebSocketWriterActorInternalMessage::WebSocketReaderActorChannelSenderClosed | WebSocketWriterActorInternalMessage::WebSocketReaderActorChannelReceiverClosed | WebSocketWriterActorInternalMessage::ActorChannelSenderClosed | WebSocketWriterActorInternalMessage::ActorChannelReceiverClosed =>
{
false
}
_ =>
{
true
}
}
}
}
pub type InternalConnectionResult<T> = Result<T, WebSocketWriterActorInternalMessage>;