use crate::{
error::{CallError, DisconnectionError, RecvError, SendError},
timeout::Timeout,
websocket::WebSocket,
};
use async_tungstenite::tokio::{ConnectStream, TokioAdapter};
use core::time::Duration;
use future_form::Sendable;
use futures::future::BoxFuture;
use subduction_core::{
connection::{
Connection,
message::{BatchSyncRequest, BatchSyncResponse, Message, RequestId},
},
peer::id::PeerId,
};
use tokio::net::TcpStream;
#[derive(Debug, Clone)]
pub enum UnifiedWebSocket<O: Timeout<Sendable> + Send + Sync> {
Accepted(WebSocket<TokioAdapter<TcpStream>, Sendable, O>),
Dialed(WebSocket<ConnectStream, Sendable, O>),
}
impl<O: Timeout<Sendable> + Send + Sync> UnifiedWebSocket<O> {
pub async fn listen(&self) -> Result<(), crate::error::RunError> {
match self {
UnifiedWebSocket::Accepted(in_ws) => in_ws.listen().await,
UnifiedWebSocket::Dialed(out_ws) => out_ws.listen().await,
}
}
}
impl<O: Timeout<Sendable> + Send + Sync> Connection<Sendable> for UnifiedWebSocket<O> {
type SendError = SendError;
type RecvError = RecvError;
type CallError = CallError;
type DisconnectionError = DisconnectionError;
fn peer_id(&self) -> PeerId {
match self {
UnifiedWebSocket::Accepted(in_ws) => Connection::<Sendable>::peer_id(in_ws),
UnifiedWebSocket::Dialed(out_ws) => Connection::<Sendable>::peer_id(out_ws),
}
}
fn next_request_id(&self) -> BoxFuture<'_, RequestId> {
match self {
UnifiedWebSocket::Accepted(in_ws) => Connection::<Sendable>::next_request_id(in_ws),
UnifiedWebSocket::Dialed(out_ws) => Connection::<Sendable>::next_request_id(out_ws),
}
}
fn disconnect(&self) -> BoxFuture<'_, Result<(), Self::DisconnectionError>> {
match self {
UnifiedWebSocket::Accepted(in_ws) => Connection::<Sendable>::disconnect(in_ws),
UnifiedWebSocket::Dialed(out_ws) => Connection::<Sendable>::disconnect(out_ws),
}
}
fn send(&self, message: &Message) -> BoxFuture<'_, Result<(), Self::SendError>> {
match self {
UnifiedWebSocket::Accepted(in_ws) => Connection::<Sendable>::send(in_ws, message),
UnifiedWebSocket::Dialed(out_ws) => Connection::<Sendable>::send(out_ws, message),
}
}
fn recv(&self) -> BoxFuture<'_, Result<Message, Self::RecvError>> {
match self {
UnifiedWebSocket::Accepted(in_ws) => Connection::<Sendable>::recv(in_ws),
UnifiedWebSocket::Dialed(out_ws) => Connection::<Sendable>::recv(out_ws),
}
}
fn call(
&self,
req: BatchSyncRequest,
timeout: Option<Duration>,
) -> BoxFuture<'_, Result<BatchSyncResponse, Self::CallError>> {
match self {
UnifiedWebSocket::Accepted(ws) => Connection::<Sendable>::call(ws, req, timeout),
UnifiedWebSocket::Dialed(ws) => Connection::<Sendable>::call(ws, req, timeout),
}
}
}
impl<O: Timeout<Sendable> + Send + Sync> PartialEq for UnifiedWebSocket<O> {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(UnifiedWebSocket::Accepted(a), UnifiedWebSocket::Accepted(b)) => a == b,
(UnifiedWebSocket::Dialed(a), UnifiedWebSocket::Dialed(b)) => a == b,
_ => false,
}
}
}