#![cfg(not(target_arch = "wasm32"))]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct WebRTCSignalMessage {
#[serde(default = "default_webrtc_transport")]
pub transport: String,
#[serde(rename = "type")]
pub signal_type: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub negotiation_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sdp: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub candidate: Option<serde_json::Value>,
}
fn default_webrtc_transport() -> String {
"webrtc".to_string()
}
pub type NativeWebRTCSignalSender = std::sync::Arc<
dyn Fn(serde_json::Value) -> futures::future::BoxFuture<'static, ()> + Send + Sync,
>;
pub type NativeWebRTCMessageHandler =
std::sync::Arc<dyn Fn(bytes::Bytes) -> futures::future::BoxFuture<'static, ()> + Send + Sync>;
pub type NativeWebRTCMessageInterceptor =
std::sync::Arc<dyn Fn(bytes::Bytes) -> futures::future::BoxFuture<'static, bool> + Send + Sync>;
pub type NativeMoQMessageHandler =
std::sync::Arc<dyn Fn(bytes::Bytes) -> futures::future::BoxFuture<'static, ()> + Send + Sync>;
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub enum NativeWebRTCState {
Idle,
Connecting,
Connected,
Failed,
Closed,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub enum NativeMoQState {
Idle,
Connecting,
Connected,
Failed,
Closed,
}
#[cfg(all(not(target_arch = "wasm32"), feature = "transport-webrtc"))]
pub mod webrtc;
#[cfg(all(not(target_arch = "wasm32"), feature = "transport-webrtc"))]
pub use webrtc::{NativeWebRTCDataChannel, NativeWebRTCRole};
#[cfg(all(not(target_arch = "wasm32"), feature = "transport-moq"))]
pub mod moq;
#[cfg(all(not(target_arch = "wasm32"), feature = "transport-moq"))]
pub use moq::NativeMoQSession;
#[cfg(not(feature = "transport-webrtc"))]
#[derive(Debug, Clone)]
pub struct NativeWebRTCDataChannel {
state: std::sync::Arc<std::sync::atomic::AtomicU8>,
negotiation_id: String,
}
#[cfg(not(feature = "transport-webrtc"))]
impl NativeWebRTCDataChannel {
pub async fn new(
_local_node_id: &str,
_remote_node_id: &str,
_config: &crate::client::WebRTCConfig,
_signal_sender: NativeWebRTCSignalSender,
negotiation_id: &str,
) -> anyhow::Result<Self> {
Ok(Self {
state: std::sync::Arc::new(std::sync::atomic::AtomicU8::new(0)),
negotiation_id: negotiation_id.to_string(),
})
}
pub fn negotiation_id(&self) -> String {
self.negotiation_id.clone()
}
pub fn state(&self) -> NativeWebRTCState {
match self.state.load(std::sync::atomic::Ordering::SeqCst) {
1 => NativeWebRTCState::Connecting,
2 => NativeWebRTCState::Connected,
3 => NativeWebRTCState::Failed,
4 => NativeWebRTCState::Closed,
_ => NativeWebRTCState::Idle,
}
}
pub async fn start(&self) -> anyhow::Result<()> {
self.state.store(3, std::sync::atomic::Ordering::SeqCst);
Ok(())
}
pub async fn handle_signal(&self, _signal: WebRTCSignalMessage) -> anyhow::Result<()> {
Ok(())
}
pub async fn send(&self, _data: &[u8]) -> anyhow::Result<()> {
anyhow::bail!("native webrtc feature is disabled")
}
pub async fn set_message_handler(&self, _handler: NativeWebRTCMessageHandler) {}
pub async fn add_message_interceptor(&self, _interceptor: NativeWebRTCMessageInterceptor) {}
pub fn close(&self) {
self.state.store(4, std::sync::atomic::Ordering::SeqCst);
}
}
#[cfg(not(feature = "transport-moq"))]
#[derive(Debug, Clone)]
pub struct NativeMoQSession {
state: std::sync::Arc<std::sync::atomic::AtomicU8>,
}
#[cfg(not(feature = "transport-moq"))]
impl NativeMoQSession {
pub async fn new(
_local_node_id: &str,
_remote_node_id: &str,
_config: &crate::client::MoQConfig,
) -> anyhow::Result<Self> {
Ok(Self {
state: std::sync::Arc::new(std::sync::atomic::AtomicU8::new(0)),
})
}
pub fn state(&self) -> NativeMoQState {
match self.state.load(std::sync::atomic::Ordering::SeqCst) {
1 => NativeMoQState::Connecting,
2 => NativeMoQState::Connected,
3 => NativeMoQState::Failed,
4 => NativeMoQState::Closed,
_ => NativeMoQState::Idle,
}
}
pub async fn start(&self) -> anyhow::Result<()> {
self.state.store(3, std::sync::atomic::Ordering::SeqCst);
Ok(())
}
pub async fn send(&self, _data: &[u8]) -> anyhow::Result<()> {
anyhow::bail!("native moq feature is disabled")
}
pub async fn set_message_handler(&self, _handler: NativeMoQMessageHandler) {}
pub fn close(&self) {
self.state.store(4, std::sync::atomic::Ordering::SeqCst);
}
}
pub fn native_webrtc_feature_enabled() -> bool {
cfg!(feature = "transport-webrtc")
}
pub fn native_moq_feature_enabled() -> bool {
cfg!(feature = "transport-moq")
}
pub fn native_lan_feature_enabled() -> bool {
cfg!(feature = "transport-lan")
}
#[cfg(all(test, not(feature = "transport-webrtc")))]
mod tests {
use super::NativeWebRTCDataChannel;
#[test]
fn disabled_webrtc_channel_preserves_negotiation_identity() {
let channel = NativeWebRTCDataChannel {
state: std::sync::Arc::new(std::sync::atomic::AtomicU8::new(0)),
negotiation_id: "negotiation-1".to_string(),
};
assert_eq!(channel.negotiation_id(), "negotiation-1");
}
}