use crate::command::ConnectionInfo;
use crate::packet::Packet;
use crate::protocol::{
QuicClientConfig, QuicServerConfig, TcpClientConfig, TcpServerConfig, WebSocketClientConfig,
WebSocketServerConfig,
};
use crate::{error::TransportError, SessionId};
use async_trait::async_trait;
#[derive(Debug, Clone)]
pub struct AdapterStats {
pub packets_sent: u64,
pub packets_received: u64,
pub bytes_sent: u64,
pub bytes_received: u64,
pub errors: u64,
pub last_activity: std::time::SystemTime,
}
impl Default for AdapterStats {
fn default() -> Self {
Self {
packets_sent: 0,
packets_received: 0,
bytes_sent: 0,
bytes_received: 0,
errors: 0,
last_activity: std::time::SystemTime::now(),
}
}
}
impl AdapterStats {
pub fn new() -> Self {
Default::default()
}
pub fn record_packet_sent(&mut self, size: usize) {
self.packets_sent += 1;
self.bytes_sent += size as u64;
self.last_activity = std::time::SystemTime::now();
}
pub fn record_packet_received(&mut self, size: usize) {
self.packets_received += 1;
self.bytes_received += size as u64;
self.last_activity = std::time::SystemTime::now();
}
pub fn record_error(&mut self) {
self.errors += 1;
self.last_activity = std::time::SystemTime::now();
}
}
#[async_trait]
pub trait ProtocolAdapter: Send + 'static {
type Config: ProtocolConfig;
type Error: Into<TransportError> + Send + std::fmt::Debug + 'static;
async fn send(&mut self, packet: Packet) -> Result<(), Self::Error>;
async fn close(&mut self) -> Result<(), Self::Error>;
async fn graceful_close(&mut self) -> Result<(), Self::Error> {
self.close().await
}
async fn force_close(&mut self) -> Result<(), Self::Error> {
self.close().await
}
fn connection_info(&self) -> ConnectionInfo;
fn is_connected(&self) -> bool;
fn stats(&self) -> AdapterStats;
fn session_id(&self) -> SessionId;
fn set_session_id(&mut self, session_id: SessionId);
async fn flush(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
pub trait ProtocolConfig: Send + Sync + Clone + std::fmt::Debug + 'static {
fn validate(&self) -> Result<(), ConfigError>;
fn default_config() -> Self;
fn merge(self, other: Self) -> Self;
}
pub trait DynProtocolConfig: Send + Sync + 'static {
fn protocol_name(&self) -> &'static str;
fn validate_dyn(&self) -> Result<(), ConfigError>;
fn as_any(&self) -> &dyn std::any::Any;
fn clone_dyn(&self) -> Box<dyn DynProtocolConfig>;
}
pub trait DynServerConfig: DynProtocolConfig {
fn build_server_dyn(
&self,
) -> std::pin::Pin<
Box<
dyn std::future::Future<
Output = Result<Box<dyn crate::Server>, crate::error::TransportError>,
> + Send
+ '_,
>,
>;
fn get_bind_address(&self) -> std::net::SocketAddr;
fn clone_server_dyn(&self) -> Box<dyn DynServerConfig>;
}
pub trait DynClientConfig: DynProtocolConfig {
fn build_connection_dyn(
&self,
) -> std::pin::Pin<
Box<
dyn std::future::Future<
Output = Result<Box<dyn crate::Connection>, crate::error::TransportError>,
> + Send
+ '_,
>,
>;
fn get_target_info(&self) -> String;
fn clone_client_dyn(&self) -> Box<dyn DynClientConfig>;
}
#[derive(Debug, thiserror::Error)]
pub enum ConfigError {
#[error("Invalid address '{address}': {reason}")]
InvalidAddress {
address: String,
reason: String,
#[source]
source: Option<Box<dyn std::error::Error + Send + Sync>>,
},
#[error("Invalid port {port}: {reason}\nSuggestion: Use a port between 1 and 65535")]
InvalidPort { port: u32, reason: String },
#[error("Missing required field '{field}'\nSuggestion: {suggestion}")]
MissingRequiredField { field: String, suggestion: String },
#[error("Invalid value for '{field}': {value}\nReason: {reason}\nSuggestion: {suggestion}")]
InvalidValue {
field: String,
value: String,
reason: String,
suggestion: String,
},
#[error("File not found: '{path}'\nSuggestion: {suggestion}")]
FileNotFound { path: String, suggestion: String },
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
}
impl ServerConfig for TcpServerConfig {
type Server = crate::adapters::factories::TcpServerWrapper;
fn validate(&self) -> Result<(), TransportError> {
ProtocolConfig::validate(self).map_err(|e| {
TransportError::config_error(
"protocol",
format!("TCP config validation failed: {:?}", e),
)
})
}
async fn build_server(&self) -> Result<Self::Server, TransportError> {
use crate::adapters::tcp::TcpServerBuilder;
let server = TcpServerBuilder::new()
.bind_address(self.bind_address)
.config(self.clone())
.build()
.await
.map_err(|e| {
TransportError::connection_error(
format!("Failed to build TCP server: {:?}", e),
true,
)
})?;
Ok(crate::adapters::factories::TcpServerWrapper::new(server))
}
fn protocol_name(&self) -> &'static str {
"tcp"
}
}
impl ClientConfig for TcpClientConfig {
type Connection = crate::adapters::tcp::TcpAdapter<TcpClientConfig>;
fn validate(&self) -> Result<(), TransportError> {
ProtocolConfig::validate(self).map_err(|e| {
TransportError::config_error(
"protocol",
format!("TCP config validation failed: {:?}", e),
)
})
}
async fn build_connection(&self) -> Result<Self::Connection, TransportError> {
use crate::adapters::tcp::TcpClientBuilder;
TcpClientBuilder::new()
.target_address(self.target_address)
.config(self.clone())
.connect()
.await
.map_err(|e| {
TransportError::connection_error(
format!("Failed to build TCP connection: {:?}", e),
true,
)
})
}
fn protocol_name(&self) -> &'static str {
"tcp"
}
}
impl ServerConfig for WebSocketServerConfig {
type Server = crate::adapters::factories::WebSocketServerWrapper;
fn validate(&self) -> Result<(), TransportError> {
ProtocolConfig::validate(self).map_err(|e| {
TransportError::config_error(
"protocol",
format!("WebSocket config validation failed: {:?}", e),
)
})
}
async fn build_server(&self) -> Result<Self::Server, TransportError> {
use crate::adapters::websocket::WebSocketServerBuilder;
let server = WebSocketServerBuilder::new()
.bind_address(self.bind_address)
.config(self.clone())
.build()
.await
.map_err(|e| {
TransportError::connection_error(
format!("Failed to build WebSocket server: {:?}", e),
true,
)
})?;
Ok(crate::adapters::factories::WebSocketServerWrapper::new(
server,
))
}
fn protocol_name(&self) -> &'static str {
"websocket"
}
}
impl ClientConfig for WebSocketClientConfig {
type Connection = crate::adapters::websocket::WebSocketAdapter<WebSocketClientConfig>;
fn validate(&self) -> Result<(), TransportError> {
ProtocolConfig::validate(self).map_err(|e| {
TransportError::config_error(
"protocol",
format!("WebSocket config validation failed: {:?}", e),
)
})
}
async fn build_connection(&self) -> Result<Self::Connection, TransportError> {
use crate::adapters::websocket::WebSocketClientBuilder;
WebSocketClientBuilder::new()
.target_url(&self.target_url)
.config(self.clone())
.connect()
.await
.map_err(|e| {
TransportError::connection_error(
format!("Failed to build WebSocket connection: {:?}", e),
true,
)
})
}
fn protocol_name(&self) -> &'static str {
"websocket"
}
}
impl ServerConfig for QuicServerConfig {
type Server = crate::adapters::factories::QuicServerWrapper;
fn validate(&self) -> Result<(), TransportError> {
ProtocolConfig::validate(self).map_err(|e| {
TransportError::config_error(
"protocol",
format!("QUIC config validation failed: {:?}", e),
)
})
}
async fn build_server(&self) -> Result<Self::Server, TransportError> {
use crate::adapters::quic::QuicServerBuilder;
let server = QuicServerBuilder::new()
.bind_address(self.bind_address)
.config(self.clone())
.build()
.await
.map_err(|e| {
TransportError::connection_error(
format!("Failed to build QUIC server: {:?}", e),
true,
)
})?;
Ok(crate::adapters::factories::QuicServerWrapper::new(server))
}
fn protocol_name(&self) -> &'static str {
"quic"
}
}
impl ClientConfig for QuicClientConfig {
type Connection = crate::adapters::quic::QuicAdapter<QuicClientConfig>;
fn validate(&self) -> Result<(), TransportError> {
ProtocolConfig::validate(self).map_err(|e| {
TransportError::config_error(
"protocol",
format!("QUIC config validation failed: {:?}", e),
)
})
}
async fn build_connection(&self) -> Result<Self::Connection, TransportError> {
use crate::adapters::quic::QuicClientBuilder;
QuicClientBuilder::new()
.target_address(self.target_address)
.config(self.clone())
.connect()
.await
.map_err(|e| {
TransportError::connection_error(
format!("Failed to build QUIC connection: {:?}", e),
true,
)
})
}
fn protocol_name(&self) -> &'static str {
"quic"
}
}
pub trait ServerConfig: Send + Sync + 'static {
type Server: crate::Server;
fn validate(&self) -> Result<(), TransportError>;
fn build_server(
&self,
) -> impl std::future::Future<Output = Result<Self::Server, TransportError>> + Send;
fn protocol_name(&self) -> &'static str;
}
pub trait ClientConfig: Send + Sync + 'static {
type Connection: crate::Connection;
fn validate(&self) -> Result<(), TransportError>;
fn build_connection(
&self,
) -> impl std::future::Future<Output = Result<Self::Connection, TransportError>> + Send;
fn protocol_name(&self) -> &'static str;
}