torrust_tracker/servers/udp/server/
bound_socket.rs1use std::fmt::Debug;
2use std::net::SocketAddr;
3use std::ops::Deref;
4
5use url::Url;
6
7use crate::servers::udp::UDP_TRACKER_LOG_TARGET;
8
9pub struct BoundSocket {
11 socket: tokio::net::UdpSocket,
12}
13
14impl BoundSocket {
15 pub async fn new(addr: SocketAddr) -> Result<Self, Box<std::io::Error>> {
19 let bind_addr = format!("udp://{addr}");
20 tracing::debug!(target: UDP_TRACKER_LOG_TARGET, bind_addr, "UdpSocket::new (binding)");
21
22 let socket = tokio::net::UdpSocket::bind(addr).await;
23
24 let socket = match socket {
25 Ok(socket) => socket,
26 Err(e) => Err(e)?,
27 };
28
29 let local_addr = format!("udp://{}", socket.local_addr()?);
30 tracing::debug!(target: UDP_TRACKER_LOG_TARGET, local_addr, "UdpSocket::new (bound)");
31
32 Ok(Self { socket })
33 }
34
35 #[must_use]
39 pub fn address(&self) -> SocketAddr {
40 self.socket.local_addr().expect("it should get local address")
41 }
42
43 #[must_use]
48 pub fn url(&self) -> Url {
49 Url::parse(&format!("udp://{}", self.address())).expect("UDP socket address should be valid")
50 }
51}
52
53impl Deref for BoundSocket {
54 type Target = tokio::net::UdpSocket;
55
56 fn deref(&self) -> &Self::Target {
57 &self.socket
58 }
59}
60
61impl Debug for BoundSocket {
62 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 let local_addr = match self.socket.local_addr() {
64 Ok(socket) => format!("Receiving From: {socket}"),
65 Err(err) => format!("Socket Broken: {err}"),
66 };
67
68 f.debug_struct("UdpSocket").field("addr", &local_addr).finish_non_exhaustive()
69 }
70}