1use crate::types::{ChatRequest, ChatResponse};
4use futures::prelude::*;
5use libp2p::request_response::{self, Codec, ProtocolSupport};
6use std::io;
7
8#[derive(Clone, Default)]
13pub struct ChatCodec;
14
15impl ChatCodec {
16 pub const PROTOCOL: &'static str = "/chat/1.0.0";
18}
19
20#[async_trait::async_trait]
21impl Codec for ChatCodec {
22 type Protocol = &'static str;
23 type Request = ChatRequest;
24 type Response = ChatResponse;
25
26 async fn read_request<T>(&mut self, _: &Self::Protocol, io: &mut T) -> io::Result<Self::Request>
28 where
29 T: AsyncRead + Unpin + Send,
30 {
31 let mut length_buf = [0u8; 4];
32 io.read_exact(&mut length_buf).await?;
33 let length = u32::from_be_bytes(length_buf) as usize;
34
35 let mut data = vec![0u8; length];
36 io.read_exact(&mut data).await?;
37
38 serde_json::from_slice(&data).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
39 }
40
41 async fn read_response<T>(
43 &mut self,
44 _: &Self::Protocol,
45 io: &mut T,
46 ) -> io::Result<Self::Response>
47 where
48 T: AsyncRead + Unpin + Send,
49 {
50 let mut length_buf = [0u8; 4];
51 io.read_exact(&mut length_buf).await?;
52 let length = u32::from_be_bytes(length_buf) as usize;
53
54 let mut data = vec![0u8; length];
55 io.read_exact(&mut data).await?;
56
57 serde_json::from_slice(&data).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
58 }
59
60 async fn write_request<T>(
62 &mut self,
63 _: &Self::Protocol,
64 io: &mut T,
65 req: Self::Request,
66 ) -> io::Result<()>
67 where
68 T: AsyncWrite + Unpin + Send,
69 {
70 let data =
71 serde_json::to_vec(&req).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
72 let length = data.len() as u32;
73
74 io.write_all(&length.to_be_bytes()).await?;
75 io.write_all(&data).await?;
76 io.flush().await?;
77 Ok(())
78 }
79
80 async fn write_response<T>(
82 &mut self,
83 _: &Self::Protocol,
84 io: &mut T,
85 res: Self::Response,
86 ) -> io::Result<()>
87 where
88 T: AsyncWrite + Unpin + Send,
89 {
90 let data =
91 serde_json::to_vec(&res).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
92 let length = data.len() as u32;
93
94 io.write_all(&length.to_be_bytes()).await?;
95 io.write_all(&data).await?;
96 io.flush().await?;
97 Ok(())
98 }
99}
100
101pub type ChatBehaviour = request_response::Behaviour<ChatCodec>;
103
104pub fn create_chat_behaviour() -> ChatBehaviour {
106 use std::time::Duration;
107
108 let config = request_response::Config::default().with_request_timeout(Duration::from_secs(10));
109
110 request_response::Behaviour::new([(ChatCodec::PROTOCOL, ProtocolSupport::Full)], config)
111}