use core::future::Future;
use core::net::Ipv4Addr;
use super::error::Error;
use super::socket_manager::SocketManager;
use crate::traits::PayloadWireFormat;
use crate::transport::{
BufferProvider, ChannelFactory, E2ERegistryHandle, LocalSpawner, Spawner, TransportFactory,
TransportSocket,
};
pub(super) trait BindDispatch<MD, C, R>
where
MD: PayloadWireFormat + Clone + core::fmt::Debug + Send + 'static,
C: ChannelFactory,
R: E2ERegistryHandle,
Result<super::socket_manager::ReceivedMessage<MD>, Error>:
crate::transport::BoundedPooled<C, 16>,
super::socket_manager::SendMessage<MD, C>: crate::transport::BoundedPooled<C, 16>,
Result<(), Error>: crate::transport::OneshotPooled<C>,
{
#[allow(clippy::manual_async_fn)]
fn bind_discovery(
&self,
interface: Ipv4Addr,
e2e_registry: R,
session_id: u16,
session_has_wrapped: bool,
multicast_loopback: bool,
) -> impl Future<Output = Result<SocketManager<MD, C>, Error>> + '_;
fn bind_unicast(
&self,
port: u16,
e2e_registry: R,
) -> impl Future<Output = Result<SocketManager<MD, C>, Error>> + '_;
#[allow(clippy::manual_async_fn)]
fn bind_discovery_unicast(
&self,
interface: Ipv4Addr,
e2e_registry: R,
) -> impl Future<Output = Result<SocketManager<MD, C>, Error>> + '_;
}
pub(super) struct SpawnerDispatch<F, S, BP> {
pub factory: F,
pub spawner: S,
pub buffer_provider: BP,
}
impl<MD, C, R, F, S, BP> BindDispatch<MD, C, R> for SpawnerDispatch<F, S, BP>
where
MD: PayloadWireFormat + Clone + core::fmt::Debug + Send + 'static,
C: ChannelFactory,
R: E2ERegistryHandle,
F: TransportFactory + Send + Sync + 'static,
F::Socket: Send + Sync + 'static,
for<'a> F::BindFuture<'a>: Send,
for<'a> <F::Socket as TransportSocket>::SendFuture<'a>: Send,
for<'a> <F::Socket as TransportSocket>::RecvFuture<'a>: Send,
S: Spawner + Send + Sync + 'static,
BP: BufferProvider,
Result<super::socket_manager::ReceivedMessage<MD>, Error>:
crate::transport::BoundedPooled<C, 16>,
super::socket_manager::SendMessage<MD, C>: crate::transport::BoundedPooled<C, 16>,
Result<(), Error>: crate::transport::OneshotPooled<C>,
{
#[allow(clippy::manual_async_fn)]
fn bind_discovery(
&self,
interface: Ipv4Addr,
e2e_registry: R,
session_id: u16,
session_has_wrapped: bool,
multicast_loopback: bool,
) -> impl Future<Output = Result<SocketManager<MD, C>, Error>> + '_ {
async move {
let buf = self
.buffer_provider
.claim()
.ok_or(Error::Capacity("udp_buffer"))?;
SocketManager::<MD, C>::bind_discovery_seeded_with_transport(
&self.factory,
&self.spawner,
interface,
e2e_registry,
session_id,
session_has_wrapped,
multicast_loopback,
buf,
)
.await
}
}
#[allow(clippy::manual_async_fn)]
fn bind_unicast(
&self,
port: u16,
e2e_registry: R,
) -> impl Future<Output = Result<SocketManager<MD, C>, Error>> + '_ {
async move {
let buf = self
.buffer_provider
.claim()
.ok_or(Error::Capacity("udp_buffer"))?;
SocketManager::<MD, C>::bind_with_transport(
&self.factory,
&self.spawner,
port,
e2e_registry,
buf,
)
.await
}
}
#[allow(clippy::manual_async_fn)]
fn bind_discovery_unicast(
&self,
interface: Ipv4Addr,
e2e_registry: R,
) -> impl Future<Output = Result<SocketManager<MD, C>, Error>> + '_ {
async move {
let buf = self
.buffer_provider
.claim()
.ok_or(Error::Capacity("udp_buffer"))?;
SocketManager::<MD, C>::bind_discovery_unicast_with_transport(
&self.factory,
&self.spawner,
interface,
e2e_registry,
buf,
)
.await
}
}
}
pub(super) struct LocalSpawnerDispatch<F, S, BP> {
pub factory: F,
pub spawner: S,
pub buffer_provider: BP,
}
impl<MD, C, R, F, S, BP> BindDispatch<MD, C, R> for LocalSpawnerDispatch<F, S, BP>
where
MD: PayloadWireFormat + Clone + core::fmt::Debug + Send + 'static,
C: ChannelFactory,
R: E2ERegistryHandle,
F: TransportFactory + 'static,
F::Socket: 'static,
S: LocalSpawner + 'static,
BP: BufferProvider,
Result<super::socket_manager::ReceivedMessage<MD>, Error>:
crate::transport::BoundedPooled<C, 16>,
super::socket_manager::SendMessage<MD, C>: crate::transport::BoundedPooled<C, 16>,
Result<(), Error>: crate::transport::OneshotPooled<C>,
{
#[allow(clippy::manual_async_fn)]
fn bind_discovery(
&self,
interface: Ipv4Addr,
e2e_registry: R,
session_id: u16,
session_has_wrapped: bool,
multicast_loopback: bool,
) -> impl Future<Output = Result<SocketManager<MD, C>, Error>> + '_ {
async move {
let buf = self
.buffer_provider
.claim()
.ok_or(Error::Capacity("udp_buffer"))?;
SocketManager::<MD, C>::bind_discovery_seeded_with_transport_local(
&self.factory,
&self.spawner,
interface,
e2e_registry,
session_id,
session_has_wrapped,
multicast_loopback,
buf,
)
.await
}
}
#[allow(clippy::manual_async_fn)]
fn bind_unicast(
&self,
port: u16,
e2e_registry: R,
) -> impl Future<Output = Result<SocketManager<MD, C>, Error>> + '_ {
async move {
let buf = self
.buffer_provider
.claim()
.ok_or(Error::Capacity("udp_buffer"))?;
SocketManager::<MD, C>::bind_with_transport_local(
&self.factory,
&self.spawner,
port,
e2e_registry,
buf,
)
.await
}
}
#[allow(clippy::manual_async_fn)]
fn bind_discovery_unicast(
&self,
interface: Ipv4Addr,
e2e_registry: R,
) -> impl Future<Output = Result<SocketManager<MD, C>, Error>> + '_ {
async move {
let buf = self
.buffer_provider
.claim()
.ok_or(Error::Capacity("udp_buffer"))?;
SocketManager::<MD, C>::bind_discovery_unicast_with_transport_local(
&self.factory,
&self.spawner,
interface,
e2e_registry,
buf,
)
.await
}
}
}