use async_trait::async_trait;
use std::sync::Arc;
use thiserror::Error;
use crate::types::SignalingMessage;
#[derive(Debug, Error, Clone)]
pub enum TransportError {
#[error("Connection failed: {0}")]
ConnectionFailed(String),
#[error("Send failed: {0}")]
SendFailed(String),
#[error("Receive failed: {0}")]
ReceiveFailed(String),
#[error("Timeout")]
Timeout,
#[error("Disconnected")]
Disconnected,
#[error("Not connected")]
NotConnected,
}
#[async_trait]
pub trait SignalingTransport: Send + Sync {
async fn connect(&self, relays: &[String]) -> Result<(), TransportError>;
async fn disconnect(&self);
async fn publish(&self, msg: SignalingMessage) -> Result<(), TransportError>;
async fn recv(&self) -> Option<SignalingMessage>;
fn try_recv(&self) -> Option<SignalingMessage>;
fn peer_id(&self) -> &str;
fn pubkey(&self) -> &str;
}
pub use SignalingTransport as RelayTransport;
#[async_trait]
pub trait PeerLink: Send + Sync {
async fn send(&self, data: Vec<u8>) -> Result<(), TransportError>;
async fn recv(&self) -> Option<Vec<u8>>;
fn try_recv(&self) -> Option<Vec<u8>> {
None
}
fn is_open(&self) -> bool;
async fn close(&self);
}
pub use PeerLink as DataChannel;
#[async_trait]
pub trait PeerLinkFactory: Send + Sync {
async fn create_offer(
&self,
target_peer_id: &str,
) -> Result<(Arc<dyn PeerLink>, String), TransportError>;
async fn accept_offer(
&self,
from_peer_id: &str,
offer_sdp: &str,
) -> Result<(Arc<dyn PeerLink>, String), TransportError>;
async fn handle_answer(
&self,
target_peer_id: &str,
answer_sdp: &str,
) -> Result<Arc<dyn PeerLink>, TransportError>;
}
pub use PeerLinkFactory as PeerConnectionFactory;
#[derive(Debug, Clone)]
pub struct MeshRouterConfig {
pub peer_id: String,
pub max_peers: usize,
pub hello_interval_ms: u64,
pub roots: Vec<String>,
pub debug: bool,
}
impl Default for MeshRouterConfig {
fn default() -> Self {
Self {
peer_id: String::new(),
max_peers: 10,
hello_interval_ms: 30000,
roots: Vec::new(),
debug: false,
}
}
}
pub type SignalingConfig = MeshRouterConfig;
#[async_trait]
impl<T: SignalingTransport + ?Sized> SignalingTransport for Arc<T> {
async fn connect(&self, relays: &[String]) -> Result<(), TransportError> {
(**self).connect(relays).await
}
async fn disconnect(&self) {
(**self).disconnect().await
}
async fn publish(&self, msg: SignalingMessage) -> Result<(), TransportError> {
(**self).publish(msg).await
}
async fn recv(&self) -> Option<SignalingMessage> {
(**self).recv().await
}
fn try_recv(&self) -> Option<SignalingMessage> {
(**self).try_recv()
}
fn peer_id(&self) -> &str {
(**self).peer_id()
}
fn pubkey(&self) -> &str {
(**self).pubkey()
}
}
#[async_trait]
impl<T: PeerLink + ?Sized> PeerLink for Arc<T> {
async fn send(&self, data: Vec<u8>) -> Result<(), TransportError> {
(**self).send(data).await
}
async fn recv(&self) -> Option<Vec<u8>> {
(**self).recv().await
}
fn try_recv(&self) -> Option<Vec<u8>> {
(**self).try_recv()
}
fn is_open(&self) -> bool {
(**self).is_open()
}
async fn close(&self) {
(**self).close().await
}
}