use std::fmt::{Debug, Formatter};
use std::net::SocketAddr;
use std::path::PathBuf;
use std::sync::Once;
use crate::core::io::{ChannelId, ConnectionId};
#[cfg_attr(feature = "specta", derive(specta::Type))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone)]
pub struct ConnectionInfo {
id: ConnectionId,
details: ConnectionDetails,
}
#[cfg_attr(feature = "specta", derive(specta::Type))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug)]
pub enum ConnectionDetails {
TcpServer {
bind_addr: SocketAddr,
},
TcpClient {
remote_addr: SocketAddr,
},
UdpServer {
bind_addr: SocketAddr,
},
UdpClient {
remote_addr: SocketAddr,
},
FileWriter {
path: PathBuf,
},
FileReader {
path: PathBuf,
},
#[cfg(unix)]
SockServer {
path: PathBuf,
},
#[cfg(unix)]
SockClient {
path: PathBuf,
},
SerialPort {
path: String,
baud_rate: u32,
},
Network,
#[cfg(feature = "unstable")]
Custom {
name: String,
details: String,
},
Unknown,
}
#[derive(Clone)]
pub struct ChannelInfo {
id: ChannelId,
details: ChannelDetails,
}
#[derive(Clone, Debug)]
pub enum ChannelDetails {
TcpServer {
server_addr: SocketAddr,
peer_addr: SocketAddr,
},
TcpClient {
server_addr: SocketAddr,
},
UdpServer {
server_addr: SocketAddr,
peer_addr: SocketAddr,
},
UdpClient {
server_addr: SocketAddr,
bind_addr: SocketAddr,
},
FileWriter {
path: PathBuf,
},
FileReader {
path: PathBuf,
},
#[cfg(unix)]
SockServer {
path: PathBuf,
},
#[cfg(unix)]
SockClient {
path: PathBuf,
},
SerialPort {
path: String,
baud_rate: u32,
},
#[cfg(feature = "unstable")]
Custom {
conn_name: String,
channel_name: String,
details: String,
},
Unknown,
}
impl ConnectionInfo {
#[cfg(feature = "unstable")]
#[inline(always)]
pub fn new(details: ConnectionDetails) -> Self {
Self::new_inner(details)
}
#[cfg(not(feature = "unstable"))]
#[inline(always)]
pub(crate) fn new(details: ConnectionDetails) -> Self {
Self::new_inner(details)
}
pub fn id(&self) -> ConnectionId {
self.id
}
pub fn details(&self) -> &ConnectionDetails {
&self.details
}
#[cfg(feature = "unstable")]
#[inline(always)]
pub fn make_channel_info(&self, details: ChannelDetails) -> ChannelInfo {
self.make_channel_info_inner(details)
}
#[cfg(not(feature = "unstable"))]
#[inline(always)]
pub fn make_channel_info(&self, details: ChannelDetails) -> ChannelInfo {
self.make_channel_info_inner(details)
}
fn new_inner(details: ConnectionDetails) -> Self {
Self {
id: ConnectionId::new(),
details,
}
}
fn make_channel_info_inner(&self, details: ChannelDetails) -> ChannelInfo {
ChannelInfo::new(self.id, details)
}
}
impl Debug for ConnectionInfo {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.details.fmt(f)
}
}
impl ChannelInfo {
#[cfg(feature = "unstable")]
#[inline(always)]
pub fn new(connection_id: ConnectionId, details: ChannelDetails) -> Self {
Self::new_inner(connection_id, details)
}
#[cfg(not(feature = "unstable"))]
#[inline(always)]
pub(crate) fn new(connection_id: ConnectionId, details: ChannelDetails) -> Self {
Self::new_inner(connection_id, details)
}
pub fn id(&self) -> ChannelId {
self.id
}
pub fn connection_id(&self) -> ConnectionId {
self.id.connection_id()
}
pub fn details(&self) -> &ChannelDetails {
&self.details
}
fn new_inner(connection_id: ConnectionId, details: ChannelDetails) -> Self {
Self {
id: ChannelId::new(connection_id),
details,
}
}
}
impl Debug for ChannelInfo {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.details.fmt(f)
}
}
static mut UNKNOWN_CONNECTION: Option<ConnectionInfo> = None;
static INIT_UNKNOWN_CONNECTION: Once = Once::new();
impl ConnectionInfo {
#[allow(static_mut_refs)]
pub(in crate::core) fn unknown() -> &'static ConnectionInfo {
INIT_UNKNOWN_CONNECTION.call_once(|| unsafe {
UNKNOWN_CONNECTION = Some(ConnectionInfo::new(ConnectionDetails::Unknown));
});
unsafe { UNKNOWN_CONNECTION.as_ref().unwrap() }
}
}