irc_async/proto/
irc.rs
1use bytes::BytesMut;
3use tokio_util::codec::{Decoder, Encoder, LinesCodec};
4
5use super::errors::IrcError;
6use super::message::Message;
7
8#[derive(Default)]
10pub struct IrcCodec {
11 inner: LinesCodec,
12}
13
14impl IrcCodec {
15 pub(crate) fn sanitize(mut data: String) -> String {
19 if let Some((pos, len)) = ["\r\n", "\r", "\n"]
21 .iter()
22 .flat_map(|needle| data.find(needle).map(|pos| (pos, needle.len())))
23 .min_by_key(|&(pos, _)| pos)
24 {
25 data.truncate(pos + len);
26 }
27 data
28 }
29}
30
31impl Decoder for IrcCodec {
32 type Item = Message;
33 type Error = IrcError;
34
35 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Message>, Self::Error> {
36 let result = self
37 .inner
38 .decode(src)
39 .map_err(IrcError::from)
40 .and_then(|res| res.map_or(Ok(None), |msg| msg.parse::<Message>().map(Some)));
41 println!(" << {:?}", result);
42 result
43 }
44}
45
46impl Encoder for IrcCodec {
47 type Item = Message;
48 type Error = IrcError;
49
50 fn encode(&mut self, msg: Message, dst: &mut BytesMut) -> Result<(), Self::Error> {
51 println!(">> {:?}", msg);
52 self.inner
53 .encode(IrcCodec::sanitize(msg.to_string()), dst)
54 .map_err(IrcError::from)
55 }
56}