use std::{
fmt::{self, Debug, Display},
net::SocketAddr,
};
use boxed::{BoxableConnector, BoxableListener, BoxedConnector, BoxedListener};
use futures_lite::{Future, Stream};
use futures_sink::Sink;
use mapped::MappedConnector;
use crate::{RpcError, RpcMessage};
pub mod boxed;
pub mod combined;
#[cfg(feature = "flume-transport")]
#[cfg_attr(quicrpc_docsrs, doc(cfg(feature = "flume-transport")))]
pub mod flume;
#[cfg(feature = "hyper-transport")]
#[cfg_attr(quicrpc_docsrs, doc(cfg(feature = "hyper-transport")))]
pub mod hyper;
#[cfg(feature = "iroh-transport")]
#[cfg_attr(quicrpc_docsrs, doc(cfg(feature = "iroh-transport")))]
pub mod iroh;
pub mod mapped;
pub mod misc;
#[cfg(feature = "quinn-transport")]
#[cfg_attr(quicrpc_docsrs, doc(cfg(feature = "quinn-transport")))]
pub mod quinn;
#[cfg(any(feature = "quinn-transport", feature = "iroh-transport"))]
#[cfg_attr(
quicrpc_docsrs,
doc(cfg(any(feature = "quinn-transport", feature = "iroh-transport")))
)]
mod util;
pub trait ConnectionErrors: Debug + Clone + Send + Sync + 'static {
type SendError: RpcError;
type RecvError: RpcError;
type OpenError: RpcError;
type AcceptError: RpcError;
}
pub trait StreamTypes: ConnectionErrors {
type In: RpcMessage;
type Out: RpcMessage;
type RecvStream: Stream<Item = Result<Self::In, Self::RecvError>>
+ Send
+ Sync
+ Unpin
+ 'static;
type SendSink: Sink<Self::Out, Error = Self::SendError> + Send + Sync + Unpin + 'static;
}
pub trait Connector: StreamTypes {
fn open(
&self,
) -> impl Future<Output = Result<(Self::SendSink, Self::RecvStream), Self::OpenError>> + Send;
fn map<In1, Out1>(self) -> MappedConnector<In1, Out1, Self>
where
In1: TryFrom<Self::In>,
Self::Out: From<Out1>,
{
MappedConnector::new(self)
}
fn boxed(self) -> BoxedConnector<Self::In, Self::Out>
where
Self: BoxableConnector<Self::In, Self::Out> + Sized + 'static,
{
self::BoxedConnector::new(self)
}
}
pub trait Listener: StreamTypes {
fn accept(
&self,
) -> impl Future<Output = Result<(Self::SendSink, Self::RecvStream), Self::AcceptError>> + Send;
fn local_addr(&self) -> &[LocalAddr];
fn boxed(self) -> BoxedListener<Self::In, Self::Out>
where
Self: BoxableListener<Self::In, Self::Out> + Sized + 'static,
{
BoxedListener::new(self)
}
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum LocalAddr {
Socket(SocketAddr),
Mem,
}
impl Display for LocalAddr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
LocalAddr::Socket(sockaddr) => write!(f, "{sockaddr}"),
LocalAddr::Mem => write!(f, "mem"),
}
}
}