1use async_trait::async_trait;
4use std::fmt::Debug;
5use std::sync::Arc;
6
7use crate::codec::{BincodeCodec, Codec};
8use crate::error::TransportResult;
9use crate::message::Message;
10use crate::transport::{FrameTransport, TransportStats};
11
12#[async_trait]
14pub trait MessageChannel<C: Codec = BincodeCodec>: Send + Sync + Debug {
15 async fn send(&self, message: &Message<C>) -> TransportResult<()>;
17
18 async fn recv(&self) -> TransportResult<Message<C>>;
25
26 fn is_connected(&self) -> bool;
31
32 fn is_healthy(&self) -> bool {
34 self.is_connected()
35 }
36
37 async fn close(&self) -> TransportResult<()>;
39
40 fn stats(&self) -> Option<TransportStats> {
42 None
43 }
44}
45
46#[derive(Debug)]
48pub struct MessageChannelAdapter<F: FrameTransport, C: Codec = BincodeCodec> {
49 inner: F,
50 _codec: std::marker::PhantomData<C>,
51}
52
53impl<F: FrameTransport> MessageChannelAdapter<F, BincodeCodec> {
54 pub fn new(transport: F) -> Self {
56 Self {
57 inner: transport,
58 _codec: std::marker::PhantomData,
59 }
60 }
61}
62
63impl<F: FrameTransport, C: Codec> MessageChannelAdapter<F, C> {
64 pub fn with_codec(transport: F) -> Self {
66 Self {
67 inner: transport,
68 _codec: std::marker::PhantomData,
69 }
70 }
71
72 pub fn inner(&self) -> &F {
74 &self.inner
75 }
76
77 pub fn into_inner(self) -> F {
79 self.inner
80 }
81}
82
83#[async_trait]
84impl<F: FrameTransport, C: Codec + Default> MessageChannel<C> for MessageChannelAdapter<F, C> {
85 async fn send(&self, message: &Message<C>) -> TransportResult<()> {
86 let bytes = message.encode()?;
87 self.inner.send_frame(&bytes).await
88 }
89
90 async fn recv(&self) -> TransportResult<Message<C>> {
91 let bytes = self.inner.recv_frame().await?;
92 Message::decode(bytes)
93 }
94
95 fn is_connected(&self) -> bool {
96 self.inner.is_connected()
97 }
98
99 fn is_healthy(&self) -> bool {
100 self.inner.is_healthy()
101 }
102
103 async fn close(&self) -> TransportResult<()> {
104 self.inner.close().await
105 }
106
107 fn stats(&self) -> Option<TransportStats> {
108 self.inner.stats()
109 }
110}
111
112#[async_trait]
113impl<T: MessageChannel<C> + ?Sized, C: Codec + Default> MessageChannel<C> for Arc<T> {
114 async fn send(&self, message: &Message<C>) -> TransportResult<()> {
115 (**self).send(message).await
116 }
117
118 async fn recv(&self) -> TransportResult<Message<C>> {
119 (**self).recv().await
120 }
121
122 fn is_connected(&self) -> bool {
123 (**self).is_connected()
124 }
125
126 fn is_healthy(&self) -> bool {
127 (**self).is_healthy()
128 }
129
130 async fn close(&self) -> TransportResult<()> {
131 (**self).close().await
132 }
133
134 fn stats(&self) -> Option<TransportStats> {
135 (**self).stats()
136 }
137}
138
139#[async_trait]
140impl<T: MessageChannel<C> + ?Sized, C: Codec + Default> MessageChannel<C> for Box<T> {
141 async fn send(&self, message: &Message<C>) -> TransportResult<()> {
142 (**self).send(message).await
143 }
144
145 async fn recv(&self) -> TransportResult<Message<C>> {
146 (**self).recv().await
147 }
148
149 fn is_connected(&self) -> bool {
150 (**self).is_connected()
151 }
152
153 fn is_healthy(&self) -> bool {
154 (**self).is_healthy()
155 }
156
157 async fn close(&self) -> TransportResult<()> {
158 (**self).close().await
159 }
160
161 fn stats(&self) -> Option<TransportStats> {
162 (**self).stats()
163 }
164}
165
166#[deprecated(since = "0.2.0", note = "Use MessageChannel instead")]
168pub type MessageTransport<C> = dyn MessageChannel<C>;
169
170#[deprecated(since = "0.2.0", note = "Use MessageChannelAdapter instead")]
171pub type MessageTransportAdapter<F, C> = MessageChannelAdapter<F, C>;
172
173#[cfg(test)]
174mod tests {
175 use super::*;
176 use crate::message::types::MessageType;
177 use crate::transport::channel::{ChannelConfig, ChannelFrameTransport};
178 use serde::{Deserialize, Serialize};
179
180 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
181 struct TestRequest {
182 value: i32,
183 }
184
185 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
186 struct TestResponse {
187 result: String,
188 }
189
190 #[tokio::test]
191 async fn test_message_channel_call_reply() {
192 let config = ChannelConfig::default();
193 let (t1, t2) = ChannelFrameTransport::create_pair("test", config).unwrap();
194
195 let ch1 = MessageChannelAdapter::new(t1);
196 let ch2 = MessageChannelAdapter::new(t2);
197
198 let req = TestRequest { value: 42 };
199 let call_msg: Message = Message::call("test_method", req.clone()).unwrap();
200 let msg_id = call_msg.id;
201
202 ch1.send(&call_msg).await.unwrap();
203
204 let received = ch2.recv().await.unwrap();
205 assert_eq!(received.id, msg_id);
206 assert_eq!(received.msg_type, MessageType::Call);
207 assert_eq!(received.method, "test_method");
208
209 let received_req: TestRequest = received.deserialize_payload().unwrap();
210 assert_eq!(received_req, req);
211
212 let resp = TestResponse {
213 result: "ok".to_string(),
214 };
215 let reply_msg: Message = Message::reply(msg_id, resp.clone()).unwrap();
216 ch2.send(&reply_msg).await.unwrap();
217
218 let received_reply = ch1.recv().await.unwrap();
219 assert_eq!(received_reply.id, msg_id);
220 assert_eq!(received_reply.msg_type, MessageType::Reply);
221
222 let received_resp: TestResponse = received_reply.deserialize_payload().unwrap();
223 assert_eq!(received_resp, resp);
224 }
225
226 #[tokio::test]
227 async fn test_message_channel_with_compression() {
228 use crate::message::types::CompressionType;
229
230 let config = ChannelConfig::default();
231 let (t1, t2) = ChannelFrameTransport::create_pair("compress", config).unwrap();
232
233 let ch1 = MessageChannelAdapter::new(t1);
234 let ch2 = MessageChannelAdapter::new(t2);
235
236 let large_data = TestRequest { value: 12345 };
237 let mut msg: Message = Message::call("compressed_method", large_data.clone()).unwrap();
238 msg.metadata.compression = CompressionType::Lz4;
239
240 ch1.send(&msg).await.unwrap();
241
242 let received = ch2.recv().await.unwrap();
243 assert_eq!(received.metadata.compression, CompressionType::Lz4);
244
245 let received_data: TestRequest = received.deserialize_payload().unwrap();
246 assert_eq!(received_data, large_data);
247 }
248
249 #[tokio::test]
250 async fn test_message_channel_delegation() {
251 let config = ChannelConfig::default();
252 let (t1, _t2) = ChannelFrameTransport::create_pair("delegate", config).unwrap();
253
254 let ch1 = MessageChannelAdapter::new(t1);
255
256 assert!(ch1.is_connected());
257 assert!(ch1.is_healthy());
258 assert!(ch1.stats().is_some());
259 }
260}