1use jsonrpsee::core::client::{ReceivedMessage, TransportReceiverT, TransportSenderT};
2use tokio::io::{AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, BufReader};
3
4#[derive(thiserror::Error, Debug)]
6pub enum TransportError {
7 #[error("io error: {0}")]
9 Io(#[from] std::io::Error),
10 #[error("parse error: {0}")]
12 Parse(String),
13}
14
15pub struct Sender<T>(T)
17where
18 T: AsyncWrite + Send + Unpin + 'static;
19
20#[async_trait::async_trait]
21impl<T> TransportSenderT for Sender<T>
22where
23 T: AsyncWrite + Send + Unpin + 'static,
24{
25 type Error = TransportError;
26
27 async fn send(&mut self, msg: String) -> Result<(), Self::Error> {
28 let msg_with_header = format!("Content-Length: {}\r\n\r\n{}", msg.len(), msg);
29 self.0.write_all(msg_with_header.as_bytes()).await?;
30 Ok(())
31 }
32}
33
34pub struct Receiver<T>(BufReader<T>)
36where
37 T: AsyncRead + Send + Unpin + 'static;
38
39#[async_trait::async_trait]
40impl<T> TransportReceiverT for Receiver<T>
41where
42 T: AsyncRead + Send + Unpin + 'static,
43{
44 type Error = TransportError;
45
46 async fn receive(&mut self) -> Result<ReceivedMessage, Self::Error> {
47 let mut content_length: Option<usize> = None;
48
49 let mut line = String::new();
52 loop {
53 self.0.read_line(&mut line).await?;
54 match line.as_str() {
55 "\r\n" => break,
57 line if line.starts_with("Content-Length: ") => {
59 let len = &line[16..line.len() - 2];
61 let len = len
62 .parse::<usize>()
63 .map_err(|e| TransportError::Parse(e.to_string()))?;
64 content_length = Some(len);
65 }
66 _ => {}
67 }
68 line.clear();
69 }
70
71 let content_length = content_length.ok_or(TransportError::Parse(
72 "Content-Length header not found".to_string(),
73 ))?;
74 let mut buf = vec![0; content_length];
75 self.0.read_exact(&mut buf).await?;
76 Ok(ReceivedMessage::Bytes(buf))
77 }
78}
79
80pub fn io_transport<I, O>(input: I, output: O) -> (Sender<I>, Receiver<O>)
82where
83 I: AsyncWrite + Send + Unpin + 'static,
84 O: AsyncRead + Send + Unpin + 'static,
85{
86 let sender = Sender(input);
87 let receiver = Receiver(BufReader::new(output));
88 (sender, receiver)
89}