actr_runtime/transport/
wire_handle.rs

1//! Wire Handle - Unified handle for Wire layer components
2//!
3//! Provides unified access interface to Wire layer components (WebRtcConnection/WebSocketConnection)
4//! Uses enum dispatch for zero-cost abstraction
5
6use super::error::NetworkResult;
7use super::lane::DataLane;
8use actr_protocol::PayloadType;
9
10// Re-export Wire layer connection types
11pub use crate::wire::webrtc::WebRtcConnection;
12pub use crate::wire::websocket::WebSocketConnection;
13
14/// WireHandle - Unified handle for Wire layer components
15///
16/// # Design Philosophy
17/// - Uses enum dispatch instead of trait objects, achieving zero virtual call overhead
18/// - Provides unified interface to access different Wire layer implementations
19/// - Supports connection priority comparison (WebRTC > WebSocket)
20#[derive(Clone, Debug)]
21pub enum WireHandle {
22    /// WebSocket connection handle
23    WebSocket(WebSocketConnection),
24
25    /// WebRTC connection handle
26    WebRTC(WebRtcConnection),
27}
28
29impl WireHandle {
30    /// Get connection type name
31    #[inline]
32    pub fn connection_type(&self) -> &'static str {
33        match self {
34            WireHandle::WebSocket(_) => "WebSocket",
35            WireHandle::WebRTC(_) => "WebRTC",
36        }
37    }
38
39    /// Connection priority (higher number = higher priority)
40    #[inline]
41    pub fn priority(&self) -> u8 {
42        match self {
43            WireHandle::WebSocket(_) => 0,
44            WireHandle::WebRTC(_) => 1, // WebRTC has higher priority
45        }
46    }
47
48    /// Establish connection
49    #[inline]
50    pub async fn connect(&self) -> NetworkResult<()> {
51        match self {
52            WireHandle::WebSocket(ws) => ws.connect().await,
53            WireHandle::WebRTC(rtc) => rtc.connect().await,
54        }
55    }
56
57    /// Check if connected
58    #[inline]
59    pub fn is_connected(&self) -> bool {
60        match self {
61            WireHandle::WebSocket(ws) => ws.is_connected(),
62            WireHandle::WebRTC(rtc) => rtc.is_connected(),
63        }
64    }
65
66    /// Close connection
67    #[inline]
68    pub async fn close(&self) -> NetworkResult<()> {
69        match self {
70            WireHandle::WebSocket(ws) => ws.close().await,
71            WireHandle::WebRTC(rtc) => rtc.close().await,
72        }
73    }
74
75    /// Get or create DataLane (with caching)
76    #[inline]
77    pub async fn get_lane(&self, payload_type: PayloadType) -> NetworkResult<DataLane> {
78        match self {
79            WireHandle::WebSocket(ws) => ws.get_lane(payload_type).await,
80            WireHandle::WebRTC(rtc) => rtc.get_lane(payload_type).await,
81        }
82    }
83
84    /// Create Lane (backward compatible)
85    #[inline]
86    pub async fn create_lane(&self, payload_type: PayloadType) -> NetworkResult<DataLane> {
87        self.get_lane(payload_type).await
88    }
89
90    /// Convert to WebRTC connection (if it is one)
91    #[inline]
92    pub fn as_webrtc(&self) -> Option<&WebRtcConnection> {
93        match self {
94            WireHandle::WebRTC(rtc) => Some(rtc),
95            _ => None,
96        }
97    }
98
99    /// Convert to WebSocket connection (if it is one)
100    #[inline]
101    pub fn as_websocket(&self) -> Option<&WebSocketConnection> {
102        match self {
103            WireHandle::WebSocket(ws) => Some(ws),
104            _ => None,
105        }
106    }
107
108    /// Invalidate cached lane for WebRTC connections (no-op for WebSocket).
109    #[inline]
110    pub async fn invalidate_lane(&self, payload_type: PayloadType) {
111        if let WireHandle::WebRTC(rtc) = self {
112            rtc.invalidate_lane(payload_type).await;
113        }
114    }
115}
116
117/// Wire connection status
118#[derive(Debug, Clone)]
119pub enum WireStatus {
120    /// Connecting
121    Connecting,
122
123    /// Connection ready
124    Ready(WireHandle),
125
126    /// Connection failed
127    Failed,
128}