use std::io;
use socket2::{Protocol, SockAddr, Type};
#[cfg(feature = "runtime")]
use crate::{
buf::{IoBuf, IoBufMut, VectoredBufWrapper},
BufResult,
};
use crate::{
impl_raw_fd,
net::{Socket, ToSockAddrs},
};
pub struct UdpSocket {
inner: Socket,
}
impl UdpSocket {
pub fn bind(addr: impl ToSockAddrs) -> io::Result<Self> {
super::each_addr(addr, |addr| {
Ok(Self {
inner: Socket::bind(&addr, Type::DGRAM, Some(Protocol::UDP))?,
})
})
}
pub fn connect(&self, addr: impl ToSockAddrs) -> io::Result<()> {
super::each_addr(addr, |addr| self.inner.connect(&addr))
}
pub fn try_clone(&self) -> io::Result<Self> {
Ok(Self {
inner: self.inner.try_clone()?,
})
}
pub fn peer_addr(&self) -> io::Result<SockAddr> {
self.inner.peer_addr()
}
pub fn local_addr(&self) -> io::Result<SockAddr> {
self.inner.local_addr()
}
#[cfg(feature = "runtime")]
pub async fn recv<T: IoBufMut<'static>>(&self, buffer: T) -> BufResult<usize, T> {
self.inner.recv(buffer).await
}
#[cfg(feature = "runtime")]
pub async fn recv_vectored<T: IoBufMut<'static>>(
&self,
buffer: VectoredBufWrapper<'static, T>,
) -> BufResult<usize, VectoredBufWrapper<'static, T>> {
self.inner.recv_vectored(buffer).await
}
#[cfg(feature = "runtime")]
pub async fn send<T: IoBuf<'static>>(&self, buffer: T) -> BufResult<usize, T> {
self.inner.send(buffer).await
}
#[cfg(feature = "runtime")]
pub async fn send_vectored<T: IoBuf<'static>>(
&self,
buffer: VectoredBufWrapper<'static, T>,
) -> BufResult<usize, VectoredBufWrapper<'static, T>> {
self.inner.send_vectored(buffer).await
}
#[cfg(feature = "runtime")]
pub async fn recv_from<T: IoBufMut<'static>>(
&self,
buffer: T,
) -> BufResult<(usize, SockAddr), T> {
self.inner.recv_from(buffer).await
}
#[cfg(feature = "runtime")]
pub async fn recv_from_vectored<T: IoBufMut<'static>>(
&self,
buffer: VectoredBufWrapper<'static, T>,
) -> BufResult<(usize, SockAddr), VectoredBufWrapper<'static, T>> {
self.inner.recv_from_vectored(buffer).await
}
#[cfg(feature = "runtime")]
pub async fn send_to<T: IoBuf<'static>>(
&self,
buffer: T,
addr: impl ToSockAddrs,
) -> BufResult<usize, T> {
super::each_addr_async_buf(addr, buffer, |addr, buffer| async move {
self.inner.send_to(buffer, &addr).await
})
.await
}
#[cfg(feature = "runtime")]
pub async fn send_to_vectored<T: IoBuf<'static>>(
&self,
buffer: VectoredBufWrapper<'static, T>,
addr: impl ToSockAddrs,
) -> BufResult<usize, VectoredBufWrapper<'static, T>> {
super::each_addr_async_buf(addr, buffer, |addr, buffer| async move {
self.inner.send_to_vectored(buffer, &addr).await
})
.await
}
}
impl_raw_fd!(UdpSocket, inner);